flattenChildren(...)Reactjs警告

时间:2016-05-30 17:07:11

标签: javascript reactjs

我在将数据更新为google firebase时遇到问题

这是构造函数和句柄函数:

constructor() {
    super();
    this.state = {
    done: false
  }
 this.handleDoneChange = (event) => {
  this.setState({
    done: event.target.checked
  })
  Firebase.database().ref('/items').child(this.props.item.key).update(
    {
      done: event.target.checked
    }
  );
};

}

和渲染的html

<input type="checkbox"
                 checked={this.state.done}
                 onChange={this.handleDoneChange}/>

每当我选中/取消选中该框时,它都会给我一个警告

warning.js:44 Warning: flattenChildren(...): Encountered two children with the same key, `.$-KJ1NOzrpaa5HmjRPulQ`. Child keys must be unique; when two children share a key, only the first child will be used.

但在firebase上更改了数据

任何人都知道这里发生了什么? 提前谢谢!

2 个答案:

答案 0 :(得分:0)

React使用key来确定协调列表时要执行的操作。好像你的render()功能很好 - 你能检查上面的一个或多个级别吗?我猜你有一个使用.map(...)来渲染组件数组的父组件,对于数组的每个项目,我们需要提供key。您可以使用商品的唯一ID(应该可以从Firebase获取)作为其密钥。

可以在https://facebook.github.io/react/docs/reconciliation.html#keys找到更多信息。

答案 1 :(得分:0)

我找到了解决方法,如果它可以帮助任何人以供将来参考。 我的错误在于:

componentDidMount() {
    Firebase.database().ref('/items').on("value", function (data) {
      this.setState({
        listOfItems: []
      });
      console.log(this.state.listOfItems)
      for (let key of Object.keys(data.val())) {
        this.setState({
          listOfItems: this.state.listOfItems.concat({key: key, text: data.val()[key].text, done: data.val()[key].done})
        })
      }

    }.bind(this));

  }

由于Google Firebase使用websocket,因此UI上的任何更改都会在数据库中显示,因此它会尝试在代码中添加相同的内容

this.setState({
      listOfItems: this.state.listOfItems.concat({key: key, text: data.val()[key].text, done: data.val()[key].done})
    })

所以我提供了一个不同的解决方案,添加/更新/删除数据没有错误:

componentDidMount() {
  Firebase.database().ref('/items').on("value", function (data) {
    let list = [];
    for (let key of Object.keys(data.val())) {
      let item = data.val()[key];
      item.key = key;
      list.push(item);
    }
    this.setState({
      listOfItems: list
    })
  }.bind(this));
}