【问题标题】:Merging properties of array elements with ReactJS使用 ReactJS 合并数组元素的属性
【发布时间】:2015-04-30 17:42:32
【问题描述】:

考虑这个由服务器 AJAX 请求返回的 JSON 结构:

{
  "Items": [
  {
    "ID": 1,
    "Name": "John Smith"
  },
  {
    "ID": 2,
    "Name": "Jane Doe"
  }
]}

还有一个将 JSON 数据设置为视图组件状态的 Fetch 函数:

FetchData(json => {
  this.setState({
    Items: json.Items,              
  })
})

在组件树的下方有一个带有复选框的 React 组件,其 render() 方法如下所示:

render(){
  return (
    <input type="checkbox" checked={this.props.Item.IsSelected} onClick={this.handleToggleItemEvent.bind(this)} />
    <span>{this.props.Item.Name}</span>
  );
}

主视图组件有一个handleToggleItemEvent,负责设置item的IsSelected状态:

handleToggleItemEvent(ID){
  var item = _.find(this.state.Items, item => {
    return item.ID === ID;
  });

  if(item){
    item.IsSelected = !item.IsSelected;
    this.setState({
      items: this.state.Items
    });
  }
}

如果单击第一项的复选框,则对象将如下所示:

{
  "Items": [
  {
    "ID": 1,
    "Name": "John Smith",
    "IsSelected": true
  },
  {
    "ID": 2,
    "Name": "Jane Doe"
  }
]}

因为 IsSelected 状态是应用程序内部的,而不是从服务器返回的,所以当我再次获取数据(比如通过过滤数据)时,IsSelected 属性会消失。将这些数据合并在一起的最佳方法是什么(或者这完全是一个坏主意)?我见过Immutability Helpers,但我不确定如何使用它们来合并数组中每个元素的属性。

【问题讨论】:

    标签: javascript json reactjs


    【解决方案1】:

    我不认为在模型中保留IsSelected 是最好的方法,因为IsSelected 拥有view/controller-specific 值,而其余属性是model-specific

    您可以更改模型并添加 selectedItems 字典并将 id 保留在那里(这也简化了handleToggleItemEvent):

    handleToggleItemEvent(ID){
        var selectedItems = this.state.selectedItems;
        selectedItems[ID] = true;
        this.setState({selectedItems: selectedItems})
    }
    

    您还必须更新 render 方法以检查基于 state.selectedItems 的复选框。

    我还建议在 getInitialState() 中初始化它:

    getInitialState() {
        return {selectedItems:{}};
    }
    

    【讨论】:

    • 我确实考虑了单独的数组,虽然它看起来不太正确,因为这意味着我需要在 render() 函数中合并两个“状态”以及我想要获得当前的任何其他地方选定的项目。
    • 想一想:如果稍后出于某种原因突然从服务器接收到的对象具有IsSelected 属性怎么办?你会覆盖它并在你的应用程序中引入错误。所选状态是您应用的一部分,而不是从服务器接收的对象的一部分,因此单独存储它是有意义的。
    • 我认为这对于一种状态是有意义的,但我还有其他与这些对象相关的应用程序状态以及 IsExpanded (参考查看详细信息链接,您可以在其中查看有关项)。所以现在我需要 this.state.selectedItems、this.state.expandedItems 等,所有这些都需要作为道具传递下去。如果我将客户端应用程序状态存储在仍然附加到服务器对象的单独对象中怎么办?所以我可以像 item.appState.IsSelected、item.appState.IsExpanded 一样访问它?应该防止碰撞。
    • 好吧,你可以使用appState 字典:appState = {ID1: {selected: true, expanded:false}}
    猜你喜欢
    • 2020-05-14
    • 2018-04-18
    • 1970-01-01
    • 1970-01-01
    • 2017-01-31
    • 2020-05-20
    • 2020-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多