“NextJS 将道具从 getServerSideProps 传递给子组件不起作用”

时间:2021-03-04 23:58:52

标签: redux next.js server-side-rendering redux-thunk next-redux-wrapper

我想将 Page 组件的 getServerSideProps 道具传递给子组件,但我得到 TypeError: Cannot read property 'title' of undefined

store.js

import { createStore, applyMiddleware } from 'redux';
import { createWrapper } from 'next-redux-wrapper';
import thunkMiddleware from 'redux-thunk';
import rootReducers from './reducers/index';

const bindMiddleware = (middleware) => {
  if (process.env.NODE_ENV !== 'production') {
    const { composeWithDevTools } = require('redux-devtools-extension');
    return composeWithDevTools(applyMiddleware(...middleware));
  }
  return applyMiddleware(...middleware);
};

const initStore = () => {
  return createStore(rootReducers, bindMiddleware([thunkMiddleware]));
};

export const wrapper = createWrapper(initStore);

action witm midlware redux-thunk

import { API_URL } from "../../../config";

import { ErrorAction, getPosteAction } from "../posts/actionCreator";

export const getPoste = () => {
    return async (dispatch) => {
        //dispatch(getPosteAction())

        function onSuccess(success) {
            dispatch(getPosteAction(success));
            return success;
        }

        function onError(error) {
            dispatch(ErrorAction());
            return error;
        }
        try {
            const data = await fetch(`${API_URL}posts`, {
                method: "GET",
                headers: {
                    Accept: "application/json",
                    "Content-Type": "application/json",
                },
            });
            const success = await data.json();
            console.log("posst is", success);
            return onSuccess(success);
        } catch (error) {
            return onError(error);
        }
    };
};

减速器

import { ADD_POST, GET_POST } from '../constants/posts';

const initialState = {
  loading: false,
  error: null,
};

const posteReducer = (state = initialState, action) => {
  //  const { Poste } = state

  switch (action.type) {
    case ADD_POST:
      // return Object.assign({}, state, {
      //   poste: state.Poste.concat(action.payload),
      // })
      // console.log("cocococo:", action.payload)
      return {
        ...state,
        loading: true,
        Poste: action.payload,
      };
    case GET_POST:
      return {
        ...state,
        loading: true,
        ...action.payload,
      };

    case 'ERROR':
      return {
        ...state,
        loading: false,
        Poste: [],
        error: action.msg,
      };
    default:
      return state;
  }
};
export default posteReducer;

在这对我有用,但我在 getServerSideProps 中的问题我不知道如何从动作中获取数据并将其传递给道具:/

//import { sortedPosts } from '../index';
import Accordion from '../../../../components/homeContent/Accordion';
import { getPoste } from "../../../../redux/actions/posts/actionsThunk-api";
import { wrapper } from "../../../../redux/store";

// export default async (req, res) => {
//   const resp = await fetch(`${API_URL}posts`);
//   const posts = await resp.json();
//   res.status(200).json(posts);
// };

export const getServerSideProps = wrapper.getServerSideProps(
    ({ store, req, ress }) => {
   const posts = await store.dispatch(getPoste());
    console.log("data server:", posts);
    return {
      props: {
        posts
      }
    }
    }
);

export default ({ posts }) => {
  <>
    {posts?.map((post) => (
      <Accordion key={post._id} {...post} />
    ))}
  </>;
};

如果调用 posts.title

正是在这个文件中的问题

这里是:

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Accordion from "@material-ui/core/Accordion";
import AccordionDetails from "@material-ui/core/AccordionDetails";
import AccordionSummary from "@material-ui/core/AccordionSummary";
import Typography from "@material-ui/core/Typography";
import Button from "@material-ui/core/Button";
import Avatar from "@material-ui/core/Avatar";
import Chip from "@material-ui/core/Chip";
import Box from "@material-ui/core/Box";
import Grid from "@material-ui/core/Grid";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";
import PlayArrowIcon from "@material-ui/icons/PlayArrow";

//import { useDispatch } from "react-redux";
//import { getPoste } from "../../redux/actions/posts/actionsThunk-api";

const useStyles = makeStyles((theme) => ({
    heading: {
        fontSize: theme.typography.pxToRem(15),
        flexBasis: "33.33%",
        flexShrink: 0,
    },
    secondaryHeading: {
        fontSize: theme.typography.pxToRem(15),
        color: theme.palette.text.secondary,
    },
    root: {
        width: "100%",
        padding: "5px",
    },
    chip: {
        height: "100%",
        borderRadius: "25px",
        backgroundColor: theme.palette.primary.main,
    },
    gris: {
        backgroundColor: "#232323",
        color: "#ffffff",
        borderRadius: "10px",
    },
    rotat: {
        transform: "rotate(30deg)",
    },
    derotat: {
        transform: "rotate(-30deg)",
    },
}));

export default function TheAccordion({ post }) {
    //const dispatch = useDispatch();
    const classes = useStyles();
    const [expanded, setExpanded] = React.useState(false);

    const handleChange = (panel) => (event, isExpanded) => {
        setExpanded(isExpanded ? panel : false);
    };

    // React.useEffect(() => {
    //  dispatch(getPoste());
    // }, [dispatch]);

    return (
        <div className={classes.root}>
            <Accordion
                expanded={expanded === "panel1"}
                onChange={handleChange("panel1")}
                className={expanded ? classes.gris : ""}
            >
                <AccordionSummary
                    expandIcon={
                        <ExpandMoreIcon className={expanded ? classes.gris : ""} />
                    }
                    aria-controls="panel1bh-content"
                    id="panel1bh-header"
                >
                    {!expanded ? (
                        <>
                            <Chip
                                className={classes.chip}
                                avatar={
                                    <Avatar
                                        style={{
                                            height: "50px",
                                            width: "50px",
                                            marginTop: "3px",
                                            marginBottom: "3px",
                                        }}
                                    ></Avatar>
                                }
                                label="user 77"
                            />
                            <Typography noWrap>{post.title}</Typography>
                            <Button
                                small="true"
                                color="primary"
                                startIcon={<PlayArrowIcon className={classes.rotat} />}
                            >
                                25
                            </Button>
                            <Button
                                small="true"
                                color="secondary"
                                startIcon={<PlayArrowIcon className={classes.derotat} />}
                            >
                                13
                            </Button>
                            <Typography style={{ textAlign: "center" }}>1h</Typography>
                        </>
                    ) : (
                        <div style={{ width: "100%" }}>
                            <Box display="flex" alignItems="flex-start">
                                <Box>
                                    <Avatar
                                        style={{
                                            height: "50px",
                                            width: "50px",
                                            margin: "0px",
                                            marginLeft: "5px",
                                        }}
                                    ></Avatar>
                                </Box>
                                <Box flexGrow={1} display="flex">
                                    <Box flexGrow={1}>
                                        <Typography
                                            variant="h6"
                                            color="primary"
                                            style={{ paddingLeft: "10px" }}
                                        >
                                            Carlos Wisozk
                                        </Typography>
                                    </Box>
                                    <Box>
                                        <Typography style={{ paddingTop: "10px" }}>
                                            1h ago
                                        </Typography>
                                    </Box>
                                </Box>
                            </Box>
                        </div>
                    )}
                </AccordionSummary>
                <AccordionDetails>
                    <Grid container className={classes.root}>
                        <Grid item xs={11} style={{ paddingLeft: "20px" }}>
                            <Typography
                                variant="h5"
                                style={{
                                    paddingLeft: "8px",
                                    paddingNottom: "2px",
                                    marginTop: "-5px",
                                }}
                            >
                                hello world
                            </Typography>
                            <Typography style={{ paddingLeft: "5px" }}>
                                accordetailsdion details accordion detailsvvv accordion details
                                accordion details accordion details accordion accordetailsdion
                                details accordion detailsvvv accordion details accordion details
                                accordion details accordion... <span color="primary">more</span>
                            </Typography>
                        </Grid>
                        <Grid
                            item
                            container
                            xs={1}
                            justify="flex-end"
                            alignItems="flex-end"
                        >
                            <Typography color="primary">answer</Typography>
                        </Grid>
                    </Grid>
                </AccordionDetails>
            </Accordion>
        </div>
    );
}

0 个答案:

没有答案