如何在nextjs getStaticprops或getServerSideProps中使用dispatch。

问题描述 投票:0回答:1

我是Next js的新手,我想在Next js中调用新闻api。useEffect 问题是一旦使用效果数据获取完成,用户开始输入,而不是过滤新闻数组,屏幕就会重新渲染,数据获取又开始了。

我尝试使用 getStaticprops 但其中不允许使用dispatch。

index.js

import { fetchNews } from "../store/actions/newsActions";
import NewsInfo from "../components/NewsInfo";
import { useDispatch, useSelector } from "react-redux";
import CircularProgress from "@material-ui/core/CircularProgress";

export default function Home() {
  const dispatch = useDispatch();
  const { news } = useSelector((state) => state.news);

  React.useEffect(() => {
    dispatch(fetchNews());
  }, []);
  return (
    <>
      {/* this wrapper cmp will make each headline uniquely accessible  */}
      {news?.articles ? (
        news.articles.map((article) => (
          <React.Fragment key={article.publishedAt}>
            <NewsInfo headlines={article} />
          </React.Fragment>
        ))
      ) : (
        <CircularProgress />
      )}
    </>
  );
}

Header.js

import React from "react";
import AppBar from "@material-ui/core/AppBar";
import Toolbar from "@material-ui/core/Toolbar";
import IconButton from "@material-ui/core/IconButton";
import Typography from "@material-ui/core/Typography";
import InputBase from "@material-ui/core/InputBase";
import { fade, makeStyles } from "@material-ui/core/styles";
import MenuIcon from "@material-ui/icons/Menu";
import SearchIcon from "@material-ui/icons/Search";
import { useDispatch } from "react-redux";
import { filterHeadlines } from "../store/actions/newsActions";

const useStyles = makeStyles((theme) => ({
  root: {
    flexGrow: 1,
  },
  menuButton: {
    marginRight: theme.spacing(2),
  },
  title: {
    flexGrow: 1,
    display: "none",
    [theme.breakpoints.up("sm")]: {
      display: "block",
    },
  },
  search: {
    position: "relative",
    borderRadius: theme.shape.borderRadius,
    backgroundColor: fade(theme.palette.common.white, 0.15),
    "&:hover": {
      backgroundColor: fade(theme.palette.common.white, 0.25),
    },
    marginLeft: 0,
    width: "100%",
    [theme.breakpoints.up("sm")]: {
      marginLeft: theme.spacing(1),
      width: "auto",
    },
  },
  searchIcon: {
    padding: theme.spacing(0, 2),
    height: "100%",
    position: "absolute",
    pointerEvents: "none",
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
  },
  inputRoot: {
    color: "inherit",
  },
  inputInput: {
    padding: theme.spacing(1, 1, 1, 0),
    // vertical padding + font size from searchIcon
    paddingLeft: `calc(1em + ${theme.spacing(4)}px)`,
    transition: theme.transitions.create("width"),
    width: "100%",
    [theme.breakpoints.up("sm")]: {
      width: "12ch",
      "&:focus": {
        width: "20ch",
      },
    },
  },
}));

function SearchAppBar() {
  const classes = useStyles();
  const dispatch = useDispatch();
  const [input, setInput] = React.useState("");

  return (
    <div className={classes.root}>
      <AppBar position="static">
        <Toolbar>
          <IconButton
            edge="start"
            className={classes.menuButton}
            color="inherit"
            aria-label="open drawer"
          >
            <MenuIcon />
          </IconButton>
          <Typography className={classes.title} variant="h6" noWrap>
            Material-UI
          </Typography>
          <div className={classes.search}>
            <div className={classes.searchIcon}>
              <SearchIcon />
            </div>
            <InputBase
              placeholder="Search…"
              classes={{
                root: classes.inputRoot,
                input: classes.inputInput,
              }}
              inputProps={{ "aria-label": "search" }}
              value={input}
              onChange={(e) => setInput(e.target.value)}
              onBlur={() => dispatch(filterHeadlines(input))}
            />
          </div>
        </Toolbar>
      </AppBar>
    </div>
  );
}
export default SearchAppBar;
javascript reactjs next.js serverside-javascript
1个回答
0
投票

当我们在使用useDispatch向子组件传递回调时。我们一般也应该使用Callback来避免子组件的重新渲染。

`import React, { useCallback } from 'react'
import { useDispatch } from 'react-redux'

export const CounterComponent = ({ value }) => {
  const dispatch = useDispatch()
  const incrementCounter = useCallback(
    () => dispatch({ type: 'increment-counter' }),
    [dispatch]
  )

  return (
    <div>
      <span>{value}</span>
      <MyIncrementButton onIncrement={incrementCounter} />
    </div>
  )
}

export const MyIncrementButton = React.memo(({ onIncrement }) => (
  <button onClick={onIncrement}>Increment counter</button>
))`

以上代码我参考了react-redux的官方文档。希望对大家有所帮助:)https:/react-redux.js.orgapihooks。

© www.soinside.com 2019 - 2024. All rights reserved.