我正在使用 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 中显示错误