S
S
Svyatoslav Khusamov2018-07-20 15:39:13
React
Svyatoslav Khusamov, 2018-07-20 15:39:13

Why doesn't the App component re-render when its state changes?

Why aren't oranges added when I press the `Add 1` button?
https://codesandbox.io/s/yqwkvy1n4z

import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

class Title extends React.Component {
  render() {
    return "React App";
  }
}

class App extends React.Component {
  constructor(props) {
    super(props);
    this.addFruit = this.addFruit.bind(this);
    this.state = {
      fruitList: ["Киви", "Банан", "Яблоки"]
    };
  }
  addFruit() {
    this.setState(prevState => {
      prevState.fruitList.push("Мандаринка");
      return {
        fruitList: prevState.fruitList
      };
    });
  }
  render() {
    return (
      <div className="App">
        <h1>Hello CodeSandbox</h1>
        <h2>Start editing to see some magic happen!</h2>
        <button onClick={this.add}>Добавить 1</button>
        <FruitList
          name={`Список апельсинок (${this.state.fruitList.length})`}
          list={this.state.fruitList}
        />
      </div>
    );
  }
}

class FruitList extends React.Component {
  constructor(props) {
    super(props);
    this.add = this.add.bind(this);
    this.state = {
      list: props.list
    };
  }
  add() {
    this.setState(prevState => {
      prevState.list.push("Апельсинка");
      return {
        list: prevState.list
      };
    });
  }
  render() {
    return (
      <div className="fruit-list">
        <h1>{this.props.name}</h1>
        <button onClick={this.add}>Добавить 2</button>
        <ul>
          {this.state.list.map((fruit, index) => (
            <FruitListItem key={index} text={fruit} />
          ))}
        </ul>
      </div>
    );
  }
}

class FruitListItem extends React.Component {
  render() {
    return <li className="fruit-list-item">{this.props.text}</li>;
  }
}

const rootElement = document.getElementById("root");
const titleElement = document.getElementsByTagName("title")[0];
console.log("titleElement", titleElement);
ReactDOM.render(<App />, rootElement);
ReactDOM.render(<Title />, titleElement);

Answer the question

In order to leave comments, you need to log in

3 answer(s)
S
Svyatoslav Khusamov, 2018-07-20
@khusamov

Thank you all, looks like I missed it. Instead of addFruit, I wrote add.

A
Anton Spirin, 2018-07-20
@rockon404

First, you mutate the states of both components:

this.setState(prevState => {
  prevState.fruitList.push("Мандаринка");
  return {
    fruitList: prevState.fruitList
  };
});

Which is contrary to the ideology of react.
Second, write props to state in FruitsList only in the constructor.
Well, you are passing a non-existent handler to onClick .
Corrected version.
Study, draw conclusions.

M
Mikhail Osher, 2018-07-20
@miraage

Why do people never read documentation????
https://reactjs.org/docs/state-and-lifecycle.html#...
Do Not Modify State Directly
// EDIT
What do you think prevState.fruitList.push("Mandarin") is? This is mutation in its purest form.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question