componentWillReceiveProps、static getDerivedStateFromProps与Dialog

需求

最近在做React Native项目中需要用到Picker选择器,考虑到时间成本以及项目本身样式的统一性,(实际上样式问题已经远远排在了功能需求之后),于是自己设计了一个Picker组件。Picker功能就是:点击显示弹窗,弹窗中间显示选择列表,点击列表项和取消按钮关闭弹窗同时选中项传递到父组件

组件设计

  1. props就简单设计了visiable(显示控制)style(样式)、value(默认选中项)、data(数据源),由于数据源是key:value形式,但是可能会有多种格式的key:value,就把key和value的字段也当成props传进来myKey(自定义数据源key)、name(自定义数据源value)

Tip:有个小问题,key 不能作为 props 传递,在组件中获取不到。

问题

其实无非就是一个弹窗的设计而已,但是问题也是出现在弹窗的关闭上。按照经验,组件可以由组件内部和组件外部关闭。 visiable 从props转为当前组件的state,然后操作本地的state就能实现功能。 刚开始是用getDerivedStateFromProps来做的,利用 nextProps.visiable!== prevState.visiable 返回 {visiable:nextProps.visiable}实现组件更新,问题来了,组件并没有更新。分别打印getDerivedStateFromProps的两个参数(nextProps, prevState)的时候,发现操作本地state后,getDerivedStateFromProps这个函数会执行,由于props还是之前的props就导致上一次的props覆盖掉了刚修改的state。 而componentWillReceiveProps只有一个nextprops参数,操作本地state就能改变组件状态了。但是既然官方更新了就使用最新的吧。 于是就多设计了一个props:hidden方法去更改父组件的 visiable来控制弹窗的显示与否

反思

其实想一下应该是没毛病的,react主张的就是单项数据流,保证组件数据源要单一,这样才能保证组件受控,组件显示与否要不就组件内部完成,要不就由组件外部控制,多个数据源好像确实不符合react的设计?


--------------------------2019/05/28编辑--------------------------

官方关于这个问题的说明

他们反复强调的也是一个组件的数据来源要保持唯一性,完全受控(完全依靠props去更新组件),非受控(数据只保存在组件内部的 state )

常见的错误就是把两者混为一谈。当一个派生 state 值也被 setState方法更新时,这个值就不是一个单一来源的值了。例如控制Dialog是否显示的时候,我们通过props可以在组件外部控制Dialog是否显示,但是如果我们也想在组件内部改变这个状态,对组件来说,这个数据是多来源的,导致的问题就是组件管理混乱。

  1. 受控组件: 我们通过props可以在组件外部控制。不要直接复制(mirror) props 的值到 state 中,而是去实现一个受控的组件,然后在父组件里合并两个值。比如,不要在子组件里被动的接受 props.value 并跟踪一个临时的 state.value,而要在父组件里管理 state.draftValue 和 state.committedValue,直接控制子组件里的值。这样数据才更加明确可预测。

  2. 不受控的组件,当你想在 prop 变化(通常是 ID )时重置 state 的话,可以选择一下几种方式: 建议: 重置内部所有的初始 state,使用 key 属性 选项一:仅更改某些字段,观察特殊属性的变化(比如 props.userID)。 选项二:使用 ref 调用实例方法。

所以,设计组件时,重要的是确定组件是受控组件还是非受控组件

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值