react派生状态的一点思考

2020-08-28  本文已影响0人  DoEmpty

这篇文章记录在做一个编辑弹框时,遇到表单加载初始数据以及维护用户修改数据问题的一个心路历程

在这里,先了解一下受控和非受控的概念:
  • 受控组件:组件内的数据是通过props传入的,受到父组件影响,自己无法控制数据
  • 非受控组件:组件内的数据是完全由自己维护了一份state,自己来管理自己的数据
思考的缘起

再次回到react上,接手一个新功能模块(特权价-企业内购)的开发,其中有一个功能是弹框编辑。刚刚学习了dva,于是也想把它用起来,信心满满开始编码

以上数据完美渲染,好像没有一点问题,开开心心进行下一步,准备处理用户输入的数据了。
到这里,问题来了表单渲染的数据来自于props,但是props的数据是不能直接修改的,怎么办,我怎么保存用户输入的数据?

想到了两个方案

  • 方案一:
    监听表单项的onChange事件,将数据维护在state里,submit的时候把propsstate的数据合并提交
  • 带来的问题:
    1.如果表单项比较多,那submit时候的数据合并会很麻烦很麻烦。
    2.如果表单存在联动,例如修改了A需要联动B的内容,怎么办?因为渲染的数据来自props,所以就算在A的onChange中修改了B,也没法渲染到视图
  • 方案二:
    派生状态,在钩子函数componentWillReceiveProps中根据接收到的props重新去派生一份state,组件里数据渲染也好维护也好都针对state。
  • 带来的问题:
    当父组件重新渲染时,哪怕子组件接受的props没有变化,也会触发子组件的componentWillReceiveProps,设想意向用户开开心心正在输入,但是因为父组件的某个状态变化导致我们在子组件的componentWillReceiveProps中派生状态的代码触发,然后用户输入的信息全部被还原成初始props,然后崩溃。

当然在方案二中的componentWillReceiveProps可以通过对比新旧props对应值是否变更来解决说到的问题,但是如果是一个比较庞大复杂的数据是不是也会很头疼

问题总结

其实以上两个方案带来的问题都是因为子组件表单中的数据来源不统一
不统一就在于,表单需要渲染的初始数据来自于父组件的props传递,但是因为用户输入或联动又需要在本地维护一份数据。
因为一个编辑表单,天然就存在着两份数据:初始数据、用户输入。由此导致我们可能需要用到派生状态,这样的话如果稍不注意就会引起问题。
而且官方文档也明确说明派生状态会导致代码冗余,并使组件难以维护

解决办法
上一篇 下一篇

猜你喜欢

热点阅读