如何解决更新redux状态时如何更新本地状态react-redux
我具有在组件内部管理的状态。 我通过将其他组件中的数据存储到redux存储中来使用它们。 但是,最后,我试图收集所有数据以进行api调用。
const [projectData,setProjectData] = useState({})
const { userData } = useSelector((state) => state.userManage);
useEffect(() => {
let newUsers = userData.map((x,i)=>({user_id:x.user_id,sub_user_id:x.sub_user_id}))
setProjectState((state) =>({...state,users:newUsers}))
},[userData ]);
// this is handler
const handleClick = () =>{
dispatch(action.createProject(projectData));
}
每当我订阅的数据发生更改时,我都会尝试更新本地状态。 不知何故,它无法正确更新。当我不使用“地图”功能而只是
setProjectState((state) =>({...state,users: userData})) <= This works.
但是它将所有内容复制到userData中, 所以我正在使用地图功能来选择特定数据,而不是所有数据。但它不起作用。
例如:
//redux store state
userData={user_id: 0,sub_id: [1,2,3],useless:"sda",useless2:"asd" }
我只想使用user_id和sub_id更新和添加本地状态
解决方法
您发布的代码很好用,也许您可以提供一个示例来说明您的问题,假设您使用的是setProjectData而不是setProjectState:
const { Provider,useDispatch,useSelector } = ReactRedux;
const { createStore,applyMiddleware,compose } = Redux;
const { useState,useEffect } = React;
const initialState = {
userData: [],};
//action types
const ADD = 'ADD';
//action creators
const userid = ((id) => () => id++)(1);
const sub = ((id) => () => id++)(1);
const add = () => ({
type: ADD,payload: {
user_id: userid(),sub_user_id: sub(),other: 'not used',},});
const reducer = (state,{ type,payload }) => {
if (type === ADD) {
return {
...state,userData: [payload,...state.userData],};
}
return state;
};
//selectors
const selectUserData = (state) => state.userData;
//creating store with redux dev tools
const composeEnhancers =
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
reducer,initialState,composeEnhancers(
applyMiddleware(() => (next) => (action) =>
next(action)
)
)
);
const UserList = () => {
const [projectData,setProjectData] = useState({});
const userData = useSelector(selectUserData);
useEffect(() => {
let newUsers = userData.map((x,i) => ({
user_id: x.user_id,sub_user_id: x.sub_user_id,}));
setProjectData((state) => ({
...state,users: newUsers,}));
},[userData]);
return (
<div>
userData:
<pre>{JSON.stringify(userData,undefined,2)}</pre>
projectData:
<pre>{JSON.stringify(projectData,2)}</pre>
</div>
);
};
const App = () => {
const dispatch = useDispatch();
return (
<div>
<button onClick={() => dispatch(add())}>
add data
</button>
<UserList />
</div>
);
};
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script>
<div id="root"></div>
但是;与其复制数据,不如最好只是编写一个选择器以所需的方式获取数据:
const { Provider,compose } = Redux;
const { createSelector } = Reselect;
const initialState = {
userData: [],};
}
return state;
};
//selectors
const selectUserData = (state) => state.userData;
const selectProjectData = createSelector(
[selectUserData],//re use selectUserData
(userData) =>
//modify user data to project data
userData.map((x,}))
);
//creating store with redux dev tools
const composeEnhancers =
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
reducer,composeEnhancers(
applyMiddleware(() => (next) => (action) =>
next(action)
)
)
);
const UserList = () => {
//no state,no effect,just select the way you want it
const projectData = useSelector(selectProjectData);
//if you want userData as well you can select that too
// const userData = useSelector(selectUserData)
return (
<div>
<pre>{JSON.stringify(projectData,document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/reselect/4.0.0/reselect.min.js"></script>
<div id="root"></div>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。