我正在使用redux,不知道为什么我在尝试访问时会获得初始状态,但它在redux开发工具中显示更新状态。
我在做什么:我有两个按钮**“Yes”,“No”,在reducer中,我有初始状态,所以当我点击“yes”按钮时,我使用调度方法更新初始状态,我能够在redux dev工具中看到更新的状态,但是当我在“No”**按钮的点击功能中从redux访问状态时,它显示初始状态:
reducer.js
import { SET_MODAL_DETAILS, CLEAR_MODAL_DETAILS } from "../actions/types";
const initialState = {
modalInfo: {
isOpen: false,
modalName: "",
title: "",
content: "",
},
};
const modal = (state = initialState, action) => {
const { type, payload } = action;
switch (type) {
case SET_MODAL_DETAILS:
return { ...state, modalInfo: payload };
case CLEAR_MODAL_DETAILS:
return { ...state, modalInfo: null };
default:
return state;
}
};
export default modal;
action.js
import {SET_MODAL_DETAILS, CLEAR_MODAL_DETAILS} from "./types";
export const setModalDetails = (payload) => ({
type: SET_MODAL_DETAILS,
payload: payload,
});
export const clearModalDetails = () => ({
type: CLEAR_MODAL_DETAILS,
});
store.js
import { createStore, applyMiddleware } from "redux";
import { composeWithDevTools } from "redux-devtools-extension";
import thunk from "redux-thunk";
import rootReducer from "./reducers";
import checkTokenExpiration from "./checkToken";
const middleware = [thunk];
const store = createStore(
rootReducer,
process.env.NODE_ENV === "production"
? applyMiddleware(...middleware, checkTokenExpiration)
: composeWithDevTools(applyMiddleware(...middleware, checkTokenExpiration))
);
export default store;
student.js
import { connect } from "react-redux";
import Button from "@mui/material/Button";
import { setModalDetails } from "../../redux/actions/modal";
const Student = ({ setModalDetails, modal: { modalInfo } }) => {
const handleYesButton = () => {
setModalDetails({
...modalInfo,
isOpen: true,
title: "Confirm Modal",
content: "Do you want to change status?",
modalName: "confirmModal",
});
};
const handleNoButton = () => {
console.log(modalInfo); // returns initial state while I have updated via above funtion
};
return (
<>
<Button onClick={handleYesButton}>Yes</Button>
<Button onClick={handleNoButton}>No</Button>
</>
);
};
const mapStateToProps = (state) => ({
modal: state.modal,
});
export default connect(mapStateToProps, { setModalDetails })(Student);
1条答案
按热度按时间70gysomp1#
如果我从父组件传递这两个函数,那么它就不会像预期的那样工作,但是如果我在子组件中使用这两个函数,比如在
student.js
中,那么它就可以工作。你能说说原因吗?这一切都在
Student
(student.js)中工作,因为Student
直接订阅了存储中的state.modal
状态。当存储更新时,Student
将重新呈现,并将最新选择的modal
状态值作为prop注入,modal.modalInfo
将重新包含在handleNoButton
函数范围中。当单击“no”按钮时,它具有当前的modalInfo
值。在
StudentA
(studentA.js)中按钮单击处理程序 * 不 * 工作的情况下,这是因为您关闭了state.modal.modalInfo
的某个本地状态的陈旧副本,该副本从未更新。当redux状态被更新并且
Parent
重新呈现时,setConfirmOptions
不会被调用来更新confirmOptions
的值,因此StudentA
被传递给当前的confirmOptions
状态,该状态现在包含陈旧的redux状态值。如果你想创建一个传递的选项对象,那么只需要直接计算并传递它。这样,在
Parent
渲染的任何时候,都会使用当前选定的状态值创建新的confirmOptions
对象。示例:
如果这样做会触发更多的
StudentA
渲染,或者创建对象的计算量很大,那么应该使用useMemo
钩子来记忆并提供一个稳定的选项对象。但是,请注意,handleYesButton
和handleNoButton
在创建confirmOptions
对象时是外部依赖项,因此它们也需要被存储以提供稳定的引用。示例:
或者因为
handleYesButton
和handleNoButton
在Parent
中的其他地方没有被引用,所以它们可以被移动到useMemo
钩子回调中。