Reactjs 有没有比使用forceUpdate更好的方法
我只是好奇,这是否是forceUpdate的一个好用法,或者是否有更好的方法来实现这一点,因为它不被鼓励。我有一个呈现name属性的组件,它需要可编辑,以便用户可以重命名该功能,但是name属性存储在Flux或React之外,因为它是Esri JavaScript API图形层的一部分。例如,我的图形层中有一个JSON如下所示的功能:Reactjs 有没有比使用forceUpdate更好的方法,reactjs,Reactjs,我只是好奇,这是否是forceUpdate的一个好用法,或者是否有更好的方法来实现这一点,因为它不被鼓励。我有一个呈现name属性的组件,它需要可编辑,以便用户可以重命名该功能,但是name属性存储在Flux或React之外,因为它是Esri JavaScript API图形层的一部分。例如,我的图形层中有一个JSON如下所示的功能: feature = { attributes: { Name: 'Custom Drawn Feature', __source: 'draw
feature = {
attributes: {
Name: 'Custom Drawn Feature',
__source: 'draw_toolbar'
},
geometry: {...},
...
}
<div className='custom-feature__header'>
<input className='custom-feature__input' type='text' value={feature.attributes.Name} onChange={this.editName} />
<div className='custom-feature__delete pointer' onClick={this.deleteFeature}>{text[language].DELETE}</div>
</div>
目前我有一个组件,其渲染函数返回如下内容:
feature = {
attributes: {
Name: 'Custom Drawn Feature',
__source: 'draw_toolbar'
},
geometry: {...},
...
}
<div className='custom-feature__header'>
<input className='custom-feature__input' type='text' value={feature.attributes.Name} onChange={this.editName} />
<div className='custom-feature__delete pointer' onClick={this.deleteFeature}>{text[language].DELETE}</div>
</div>
我不想将名称设置为state,因为这感觉有点像一种反模式,需要道具并将其设置为state,而且现在我没有一个真实的来源,因为名称存在于组件(在UI中的多个位置使用)和图形层中的功能属性中
我还尝试设置defaultValue
而不是value
,然后没有调用forceUpdate,因为forceUpdate工作得非常好,除了UI中使用此组件的其他位置在重新安装之前没有反映出更改。我怀疑发生这种情况是因为props对象没有改变,它与更新的属性具有相同的特性
不可变很好,但是数据模型不是由我控制的,它是由Esri JavaScript API提供的,我不想存储重复的数据
回到最初的问题,这是可以接受使用forceUpdate
的情况之一,还是最好将键
值(可能像Math.random())存储在每次编辑名称时我都会更改的状态,还是另一种更好的方法
编辑:
为了澄清,该功能存储在Esri图形的图层中。这些组件只是渲染地图的状态,更新图形名称的唯一方法是通过
feature.attributes.name='newname'
直接更改其属性。需要这样做,以便其他Esri API方法和小部件可以正确显示/使用它,如弹出窗口和搜索小部件。根据您的解释和设置,我理解:
- 告诉组件外部世界
需要一个新名称的唯一方法是修改这个道具feature.attribute.Name
- 由于您的组件不会由任何具有新道具的父级重新渲染,因此可以使用
触发重新渲染forceUpdate()
forceUpdate()
,但将以下内容作为使用它的理由:
(例如:对象中深层的数据在不改变对象的情况下发生变化
(本身)
我仍然认为将feature.attribute.name
置于状态是一个更好、更干净的解决方案
以这种方式将此道具置于状态不是一种反模式。官方文档,解释将道具置于初始状态以使组件处于更新状态是完全有效的
然而,如果你明确表示道具
是组件内部受控状态的唯一种子数据
有状态的解决方案类似于:
const newName = target.value;
this.props.feature.attributes.Name = newName; // inform outside world of new name
this.setState( { name: newName });
把名字放在州里会更清楚地表明:
- 道具
仅作为初始道具传入feature.attribute.name
- 组件可能会在状态中更改名称,从而导致组件重新渲染
- DOM和in状态中的值始终同步
- 非常明确地说你是在直接变异道具,为什么
forceUpdate()
和有状态方法在技术上略有不同:
将跳过任何forceUpdate()
(如果newname==previousname,DOM diff引擎仍将阻止更新)shouldComponentUpdate()
- 告诉组件外部世界
需要一个新名称的唯一方法是修改这个道具feature.attribute.Name
- 由于您的组件不会由任何具有新道具的父级重新渲染,因此可以使用
触发重新渲染forceUpdate()
forceUpdate()
,但将以下内容作为使用它的理由:
(例如:对象中深层的数据在不改变对象的情况下发生变化
(本身)
我仍然认为将feature.attribute.name
置于状态是一个更好、更干净的解决方案
以这种方式将此道具置于状态不是一种反模式。官方文档,解释将道具置于初始状态以使组件处于更新状态是完全有效的
然而,如果你明确表示道具
是组件内部受控状态的唯一种子数据
有状态的解决方案类似于:
const newName = target.value;
this.props.feature.attributes.Name = newName; // inform outside world of new name
this.setState( { name: newName });
把名字放在州里会更清楚地表明:
- 道具
仅作为初始道具传入feature.attribute.name
- 组件可能会在状态中更改名称,从而导致组件重新渲染
- DOM和in状态中的值始终同步
- 非常明确地说你是在直接变异道具,为什么
forceUpdate()
和有状态方法在技术上略有不同:
将跳过任何forceUpdate()
(如果newname==previousname,DOM diff引擎仍将阻止更新)shouldComponentUpdate()
forceUpdate
现在实际上正在工作,这是唯一一件可以做到的事情。我想把它放在状态,但我必须更新状态,更新图形层上的功能,