reactjs - react, how to not mutate state without deepcloning?
问题描述
You have data stored in a state (possibly redux state)
and You are using formik to modify your data.
In code,
let { data } = props // from redux state
// suppose data is somewhat deep like
// data = {
// p1: {
// p11: {
// },
// p12: [{
// p122
// }, {
// p123
// }]
// },
// p2
// }
const handleSubmit = (values) => {
dispatch({
type: 'setData',
payload: {
data: values
}
})
})
<Formik initialValues={_.cloneDeep(data)} enableReinitialize onSubmit={handleSubmit} />
// reducer looks like
const reducer = (state={}, action) => {
return produce(state, (draft) => {
if (action.type === 'setData') {
draft.data = action.payload.data
}
})
}
notice I'm cloning data
with _.cloneDeep(data)
to prevent mutating the state.
When data is flat, it's safe to get away with {...data}
but when data are deep (have objects that have objects) it's not that easy
Is there an alternative way than deep cloning?
I was wondering if immer.js
could help here.
解决方案
我不确定我是否理解这个问题,因为目前还不清楚为什么你首先需要 deepClone,除非你的减速器有副作用并且改变了有效载荷而不是状态。在这种情况下,您也可以调用produce
有效负载数据,例如:
const reducer = (state={}, action) => {
return produce(state, (draft) => {
if (action.type === 'setData') {
const dataToStore = produce(action.payload, payloadDraft => {
payloadDraft.name = payloadDraft.name.toUpperCase()
})
draft.data = dataToStore
}
})
}
推荐阅读
- git - 我做了一个 git push --force 现在我的 git 疯了
- flutter - Flutter:使剪切区域透明以滚动 ListView
- css - 盒子阴影被 Css Grid Masonry 效果剪裁
- sql-server - 多线串到线串
- javascript - 反应 array.map 错误
- java - 尝试从父静态类型对象访问子方法时有什么好的做法?
- java - 在 Spring Boot 中在 @ExceptionHandler 中抛出另一个异常不起作用
- python - Spark:基于模式填充空值的干净方法
- amazon-web-services - 适用于 UpdateEnvironment 的 AWS InsufficientPrivilegesException 但我已设置相关权限
- python - Kivy android前台服务 - 服务重启后无法打开应用程序(案例应用程序从最近的应用程序中刷出)