1

我正在使用 next.js 不可变 Js 和 redux saga。

错误:从“/me/profile-setting”中.initialState.ui返回的 错误序列化。getServerSideProps原因:object ("[object Object]") 无法序列化为 JSON。请仅返回 JSON 可序列化数据类型。

配置文件设置:

import React from "react";
import {
  Button,
  FormControl,
  FormControlLabel,
  Grid,
  InputAdornment,
  makeStyles,
  Radio,
  RadioGroup,
  Typography,
  Avatar,
  TextField,
} from "@material-ui/core";
import { Email } from "@material-ui/icons";
import { manCategory } from "assets/constants";

const useStyles = makeStyles((theme) => ({
  root: {
    padding: theme.spacing(2),
    paddingTop: theme.spacing(3),
  },
  icon: {
    fontSize: theme.spacing(13),
  },
  radio: {
    flexDirection: "row",
  },
  deactivate: {
    color: theme.palette.error.main,
  },
  large: {
    width: theme.spacing(10),
    height: theme.spacing(10),
  },
}));

export default function ProfileSetting() {
  const classes = useStyles();
  const [canEditPersonal, setCanEditPersonal] = React.useState(false);
  const [canEditEmail, setCanEditEmail] = React.useState(false);
  const [canEditNumber, setCanEditNumber] = React.useState(false);

  return (
    <Container>
      <Grid container spacing={2}>
        <Grid item xs={12} container>
          <Avatar alt="Ameed" src={manCategory} className={classes.large} />
        </Grid>
        <Grid item xs={12} container>
          <Grid item xs={12}>
            <Typography variant="h6">
              Personal Information
              <ToggleButtons
                condition={canEditPersonal}
                toggler={setCanEditPersonal}
              />
            </Typography>
          </Grid>
          <Grid item xs={12} container spacing={2}>
            <CustomTextField
              margin="normal"
              value={"Ameed"}
              disabled={!canEditPersonal}
            />
            <CustomTextField
              margin="normal"
              value={"Faridi"}
              disabled={!canEditPersonal}
            />
          </Grid>
          <Grid item xs={12}>
            <FormControl
              component="fieldset"
              margin="normal"
              disabled={!canEditPersonal}
            >
              <RadioGroup
                aria-label="gender"
                name="gender1"
                className={classes.radio}
                value="male"
              >
                <FormControlLabel
                  value="male"
                  control={<Radio color="primary" />}
                  label="Male"
                />
                <FormControlLabel
                  value="female"
                  control={<Radio color="primary" />}
                  label="Female"
                />
              </RadioGroup>
            </FormControl>
          </Grid>
          <Grid item xs={12}>
            <Typography variant="h6">
              Email Address
              <ToggleButtons
                condition={canEditEmail}
                toggler={setCanEditEmail}
              />
            </Typography>
          </Grid>
          <Grid item xs={12}>
            <CustomTextField
              margin="normal"
              value={"faridiameed5@gmail.com"}
              disabled={!canEditEmail}
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start">
                    <Email color={canEditEmail ? "primary" : "disabled"} />
                  </InputAdornment>
                ),
              }}
            />
          </Grid>
          <Grid item xs={12}>
            <Typography variant="h6">
              Mobile Number
              <ToggleButtons
                condition={canEditNumber}
                toggler={setCanEditNumber}
              />
            </Typography>
          </Grid>
          <Grid item xs={12}>
            <CustomTextField
              margin="normal"
              value={"8218632822"}
              disabled={!canEditNumber}
              InputProps={{
                startAdornment: (
                  <InputAdornment position="start">
                    <Typography>+91 |</Typography>
                  </InputAdornment>
                ),
              }}
            />
          </Grid>
          <Grid item xs={12} container justifyContent="space-between">
            <Button color="primary" size="small">
              change my password
            </Button>
            <Button className={classes.deactivate} size="small">
              Deactivate Account
            </Button>
          </Grid>
        </Grid>
      </Grid>
    </Container>
  );
}

const ToggleButtons = ({ condition, toggler }) => {
  return condition ? (
    <>
      <Button color="primary" size="small" onClick={() => toggler(false)}>
        Save
      </Button>
      <Button color="primary" size="small" onClick={() => toggler(false)}>
        Cancel
      </Button>
    </>
  ) : (
    <Button color="primary" size="small" onClick={() => toggler(true)}>
      Edit
    </Button>
  );
};

const CustomTextField = (props) => {
  return <TextField variant="outlined" size="small" {...props} />;
};

const Container = ({ children }) => {
  const classes = useStyles();
  return <div className={classes.root}>{children}</div>;
};

减速机

import { fromJS } from "immutable";
import { HYDRATE } from "next-redux-wrapper";
import * as Actions from "modules/me/constants";

const initialState = fromJS({
  currentPage: "",
});

export default function meReducer(state = initialState, { type, payload }) {
  switch (type) {
    case Actions.SWITCH_ME_PAGE:
      return state.set("currentPage", payload);

    case HYDRATE:
      console.log({ payload });
      return state.set("currentPage", payload.me.currentPage);

    default:
      return state;
  }
}

uiReducer:

import { fromJS } from "immutable";
import * as Actions from "modules/ui/constants";
import { HYDRATE } from "next-redux-wrapper";

const initialState = fromJS({
  loader: false,

  snackbar: {
    isOpen: false,
    message: "",
    severity: "",
    duration: 1000,
    position: "",
  },

  drawer: {
    isOpen: false,
    anchor: "left",
    body: "",
  },
});

export default function uiReducer(state = initialState, { type, payload }) {
  switch (type) {
    case Actions.OPEN_LOADER:
      return state.set("loader", true);

    case Actions.CLOSE_LOADER:
      return state.set("loader", false);

    case Actions.OPEN_DRAWER:
      return state.set("drawer", fromJS(payload));

    case Actions.CLOSE_DRAWER:
      return state.set("drawer", initialState.get("drawer"));

    case Actions.OPEN_SNACKBAR:
      return state.set("snackbar", fromJS(payload));

    case Actions.CLOSE_SNACKBAR:
      return state.set("snackbar", initialState.get("snackbar"));

    case HYDRATE:
      return state;

    default:
      return state;
  }
}

我/个人资料设置:

import React from "react";

import Layout from "layout";
import { ProfileSetting } from "components/common";
import { DesktopMePages } from "components/desktop";
import { switchMePages } from "modules/me/actions";
import { detectDevice } from "utils";
import { wrapper } from "modules/store";

export default function ProfileSettings({ isMobile }) {
  return isMobile ? <Mobile /> : <Desktop />;
}

function Desktop() {
  return (
    <Layout>
      <DesktopMePages>
        <ProfileSetting />
      </DesktopMePages>
    </Layout>
  );
}
function Mobile() {
  return (
    <Layout isMobile={true} canBack={true}>
        <ProfileSetting />
    </Layout>
  );
}

export const getServerSideProps = wrapper.getServerSideProps(
  (store) => async (context) => {
    const isMobile = detectDevice(context);

    store.dispatch(switchMePages("Profile"));

    return {
      props: {
        isMobile,
      },
    };
  }
);

检测设备:

export const detectDevice = context => {
  const UA = context?.req?.headers['user-agent'];
  const isMobile = Boolean(
    UA.match(
      /Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile|WPDesktop/i,
    ),
  );

  return isMobile;
};

我无法使用不可变的 Js 从服务器发送操作。

在不可变 Js 之前,一切正常。

它在 .initialState.ui 中显示错误

4

0 回答 0