有没有比使用forceUpdate更好的方法

时间:2016-05-12 14:35:52

标签: reactjs

我很好奇这是否可以正确使用forceUpdate,或者是否有更好的方法来实现这一点,因为不鼓励使用forceUpdate。我有一个呈现name属性的组件,需要它可以编辑,因此用户可以重命名该功能,但name属性存储在Flux或React之外,因为它是Esri JavaScript API图形层的一部分。例如,我的图形层中有一个功能,其JSON如下所示:

feature = {
  attributes: {
    Name: 'Custom Drawn Feature',
    __source: 'draw_toolbar'
  },
  geometry: {...},
  ...
}

目前我有一个组件,其render函数返回如下内容:

<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>

以及更新名称的editName函数:

editName = ({target}) => {
  const {feature} = this.props;
  feature.attributes.Name = target.value;
  this.forceUpdate();
};

我不想将名称设置为州,因为感觉有点像采取道具并将其设置为状态的反模式,而且现在我从来没有单一的真相来源名称存在于组件(在UI中的多个位置使用)和图形层中的要素属性中。

我还尝试设置defaultValue而不是value,然后不调用功能非常好的forceUpdate,除了使用此组件的UI中的其他位置在重新装入之前未反映更改。我怀疑是因为道具对象没有改变,它与更新属性的功能相同。

不可变,但数据模型不受我控制,它由Esri JavaScript API提供,我不想存储重复数据。

回到最初的问题,使用forceUpdate是否可接受这种情况之一,或者更好地存储key值(可能像Math.random())说明每次编辑名称时我都会改变,还是他们的另一种更好的方式?

编辑: 只是为了澄清,该功能存储在Esri Graphic的图层中。这些组件只是呈现地图的状态,更新图形名称的唯一方法是直接通过feature.attributes.Name = 'New Name'更改它的属性。这需要这样做,以便其他Esri API方法和小部件可以正确显示/使用它,如弹出窗口和搜索小部件。

1 个答案:

答案 0 :(得分:0)

根据您的解释和设置,我理解:

  • feature.attribute.Name需要新名称的组件之外告诉世界的唯一方法是改变这个道具。
  • 因为任何具有新道具的父级都不会重新呈现您的组件,所以您使用forceUpdate()来触发重新渲染。

虽然反应排序允许forceUpdate()用于此目的(see docs here),但是通过命名以下作为使用它的理由:

  

(例如:对象深处的数据在不更改对象的情况下发生变化   本身)

我仍然认为feature.attribute.name置于状态是更好,更清洁的解决方案

以这种方式将这个道具置于状态是反模式。关于props in initialstate here的官方文档解释说,为了具有组件更新状态,将props置于 初始 状态是完全有效的。

  

然而,如果你明确说明道具,它不是反模式   仅是组件内部控制状态的种子数据

状态解决方案看起来像:

const newName = target.value;
this.props.feature.attributes.Name = newName; // inform outside world of new name
this.setState( { name: newName }); 

将名称置于状态使得更清楚:

  • 道具feature.attribute.name仅作为初始道具传递
  • 您的组件可能会更改状态中的名称,从而导致组件重新呈现。
  • DOM和状态中的值始终同步
  • 明确表示你是在直接改变一个道具,为什么

PS:forceUpdate()和有状态方法之间在技术上略有不同:

  • forceUpdate()将跳过任何shouldComponentUpdate()(如果newname == previousname,DOM diff引擎仍会阻止更新)