如何在handleChange函数中以React状态更改键值对?

时间:2019-04-11 20:12:08

标签: reactjs

react App.js中的状态值之一是字典,其结构如下(过滤器):

constructor(props) {
  super(props);
  this.state = {
    cars: [], 
    filteredCars: [],
    filters: {
      "color": null,
      "hasSunroof": null,
      "isFourWheelDrive": null,
      "hasLowMiles": null, 
      "hasPowerWindows": null,
      "hasNavigation": null, 
      "hasHeatedSeats": null
    }
  };
}

我如何修改例如在选中复选框时运行的handleColorChange函数中的“ hasSunroof”?尝试执行以下操作给我语法错误:

handleSunroofChange(event) {
    this.setState({filters["hasSunroof"]: event.target.value});
}

3 个答案:

答案 0 :(得分:1)

反应的setState不会递归合并。当我们需要更新状态中的对象时,我们需要确保使用顶级属性调用setState,该顶级属性包含所有现有属性以及任何新属性。

为此,我们需要访问先前的状态,可以通过提供对setState的回调来获得该状态。一旦有了先前的状态,就可以使用它来构建新状态,如下所示:

handleSunroofChange(event) {
    this.setState(prevState => ({
      filters: {
        ...prevState.filters,
        hasSunRoof: event.target.value,
      }
    }));
}

在更新this.state.filters的值时,必须进行扩展以保持this.state.filters.hasSunRoof的所有现有属性

编辑:

每个@hyde的注释,确保在构造函数中为this绑定handleSunroofChange()或使用箭头函数语法将函数定义为类属性:

handleSunroofChange = (event) => {
    this.setState(prevState => ({
      filters: {
        ...prevState.filters,
        hasSunRoof: event.target.value,
      }
    }));
}

答案 1 :(得分:1)

即使这里的其余答案完全可以解决您的问题,我也要考虑您要构建的内容。从过滤器的数量来看,将有相应的复选框。那么为每个单独的过滤器制作方法并不理想。

说,您有几个复选框(在这里考虑2)

  <div>
    <input
      name="hasSunroof"
      onChange={this.toggleOnChangeHandler}
      type="checkbox"
    />
    <input
      name="isFourWheelDrive"
      onChange={this.toggleOnChangeHandler}
      type="checkbox"
    />
  </div>

我给每个复选框一个name属性,表示它们所对应的过滤器。然后,用于处理所有复选框的 single 方法将是:

  toggleOnChangeHandler = e => {
    // Deriving the filter that a checkbox is associated too, and getting its value on change    
    const property = e.target.name;
    const val = e.target.value;
    this.setState(
      prevState => {
        // Taking a copy of the initial filters obj         
        const { filters } = prevState;
        // Updating it's property as per the key, value pair retrieved (key being the filter, value being "on" or "off")        
        filters[property] = val;
        // Returning the updated object         
        return { filters };
      },
      // Since setState is async, all operations that require the updated state, should be done here       
      () => {
        console.log(this.state);
      }
    );
  };

假设其中的初始state包含filters对象:

  filters: {
    color: null,
    hasSunroof: null,
    isFourWheelDrive: null,
    hasLowMiles: null,
    hasPowerWindows: null,
    hasNavigation: null,
    hasHeatedSeats: null
  }

这里是codepen供参考。

请注意:

  1. 我正在使用箭头函数来定义您的类方法,但是如果您选择不这样做,请不要忘记在bindconstructor进行定义。
  2. setState中的匿名箭头函数是一个回调,用于在状态更新后执行所需的任何操作,您可以选择删除该状态。

答案 2 :(得分:0)

在React状态下,您不需要将密钥包装在字符串中,这在Javascript objec t

中是不必要的

这应该可以工作:

handleSunRoofChange = (event) => {
 this.setState({
  filters: {
     hasSunRoof: event.target.value
   } 
 })
}