如何将State设置为新对象?

时间:2019-02-09 12:45:08

标签: javascript reactjs

我正在学习React,所以也许我正在解决这个错误,但是我有一个对象包含来自父组件的状态数组(目前只是硬编码的虚拟数据),并且我在按钮上有一个点击处理程序在子组件中,当单击该子组件时,会对该数组进行随机混洗/重新排序,我希望在发生这种情况后立即(通过映射)重新渲染页面上数组中的项。

当我对新状态进行console.log时,它每次都会记录新状态,但是不会更新/重新呈现页面上的内容。我想念什么或做错什么?为什么我的州不更新页面上的项目?

我只包含代码的相关部分。我不包含随机播放功能,但知道它可以正常工作。

// From the parent component:

componentDidMount() {
    this.setState({
        meals: [
            {
                id: 1,
                name: "Pizza",
                ingredients: [
                    "dough",
                    "cheese",
                    "sauce"
                ]
            },
            {
                id: 2,
                name: "Pasta",
                ingredients: ["Pasta", "Sauce"]
            }
        ]
    });
}

// From the child component:

constructor(props) {
    super(props);
    this.state = {
        meals: props.meals
    };
    this.generateNewMealPlan = this.generateNewMealPlan.bind(this);
    this.shuffle = this.shuffle.bind(this);
}

shuffle(array) {
    var currentIndex = array.length,
        temporaryValue,
        randomIndex;

    // While there remain elements to shuffle...
    while (0 !== currentIndex) {
        // Pick a remaining element...
        randomIndex = Math.floor(Math.random() * currentIndex);
        currentIndex -= 1;

        // And swap it with the current element.
        temporaryValue = array[currentIndex];
        array[currentIndex] = array[randomIndex];
        array[randomIndex] = temporaryValue;
    }

    return array;
}

generateNewMealPlan() {
    const newMeals = this.shuffle(this.props.meals);
    this.setState({ meals: newMeals }, function() {
      console.log(this.state.meals);
    });
}

render() {
    return (<button type="button" onClick={this.generateNewMealPlan}>Generate</button>);
}

1 个答案:

答案 0 :(得分:0)

问题是您将其设置为state并映射到props。组件重新渲染有两种方法

  1. 状态发生变化时
  2. 道具发生变化

在您的情况下,您正在更改状态,但是该状态尚未在渲染器中使用(根据注释)。 因此,除了在道具上进行映射之外,您还可以在状态上进行映射

//Child Render method
render = () => {
    return (
      <div>
        <button onClick={() => this.generateNewMealPlan()}>Generate</button>
        {this.state.meals.map((obj, index) => (
          <ul>
            <li>{obj.name}</li>
            {obj.ingredients.map((ing, ind) => (
              <small>{ing} </small>
            ))}
          </ul>
        ))}
      </div>
    );
  };

这是您的问题https://codesandbox.io/s/qqqvll3686

的有效解决方案