什么时候真正使用getDerivedStateFromProps?

时间:2018-12-10 04:43:13

标签: javascript reactjs redux getderivedstatefromprops

我很难确定我的组件层次结构是否真的需要getDerivedStateFromProps,如果确实需要这种情况的程度与文档说明的一样少。这可能是对React / Redux设计的根本误解。

class AttributeList extends React.Component {
  constructor(props){
    super(props)
    this.state = {
      attributes: props.attributes,
      newAttributes: []
    }
  }

  addNewAttribute = () => {
      // add new empty attribute to newAttributes state
  }

  onKeyChange = () => {
      // update appropriate attribute key
  }

  onValueChange = () => {
      // update appropriate attribute value
  }

  saveAttributes = () => {
      // save the, API call
  }

  render = () => {
      this.state.attributes.map((pair) => {
          <Attribute
            //pass data + functions, functional component />
      })
      this.state.newAttributes.map((pair) => {
          <Attribute
            //pass data + functions, functional component />
      })
  }

  static getDerivedStateFromProps(){
      // ?? do comparisons here to choose to remove or keep certain newAttributes? or just ignore result of save and keep interface as-is, just show error message if saving failed. 
  } 
}

我有一个父组件AttributeList,它呈现了一堆Attributes,它们本质上是键值对。 AttributeList接收文档的属性列表作为道具。但是,可以编辑属性,因此可以使用this.state.attributes初始化其状态(this.props.attributes)。通常,键是不可变的,但是如果用户将新属性添加到列表中,则他可以编辑键和值。用户可以随时保存所有属性。保存新属性后,我也想禁用它们的键编辑。这是两难选择。

选项1是保存文档并只是希望它能起作用,然后清除新属性列表并将所有属性标记为已保存(禁用键输入)。我认为这将是“完全不受控制的”解决方案,其中一旦状态初始化,组件便会自行处理所有问题。但是,如果保存失败怎么办?我不想向用户显示错误的状态。

所以我想做第二种选择。保存后,获取文档,这将加载属性列表并重新渲染组件。但是,我需要摆脱我的新属性,因为它们现在是attributes道具的一部分。我想验证新属性现在实际上是attributes道具的一部分。似乎会发生在getDerivedStateFromProps中,我将在每个渲染周期中检查attributes道具中是否已经存在任何新的属性键,如果存在,则将它们从“新”列表中删除,并且返回该状态。

但这是使用getDerivedStateFromProps的正确时机吗?在我看来,对于用户正在对其进行API调用以保存它的页面进行“编辑”的任何页面,如果要基于保存的数据进行渲染(“真相”),那么我需要使用{{ 1}}。或者从设计角度来看,最好显示类似于“数据未成功保存”的消息并保持状态不变,以防止任何数据丢失。老实说,我不确定。

1 个答案:

答案 0 :(得分:0)

我看不到getDerivedStateFromProps是如何出现的,因为您没有理由将道具复制到状态中吗?如果更改了旧属性值,则将其保存到redux存储中;如果更改了新属性,则可以更新本地状态(或将它们保存到存储的其他部分中,或通过其他方式对其进行区分)。可以在更新处理程序中或在保存时合并期间强制执行更新规则。

// dispatch redux action to update store
onOldValueChange = () => {}

// this.setState to update new value
onNewKeyChange = () => {}
onNewValueChange = () => {}

render = () => {
  this.props.attributes.map((pair) => {
    <Attribute
      //pass data + onOldValueChange, functional component />
  })
  this.state.newAttributes.map((pair) => {
    <NewAttribute
      //pass data + functions, functional component />
  })
}