khusamov
@khusamov
ReactJS, NodeJS, TypeScript, Sencha ExtJS

Почему не перерисовывается компонент App при изменении его состояния?

Почему не добавляются апельсинки, если нажать кнопку `Добавить 1`?

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);
  • Вопрос задан
  • 643 просмотра
Решения вопроса 1
khusamov
@khusamov Автор вопроса
ReactJS, NodeJS, TypeScript, Sencha ExtJS
Всем спасибо, оказывается я протупил. Вместо addFruit написал add.
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
rockon404
@rockon404 Куратор тега React
Frontend Developer
Во первых вы мутируете состояния обоих компоненов:
this.setState(prevState => {
  prevState.fruitList.push("Мандаринка");
  return {
    fruitList: prevState.fruitList
  };
});

Что противоречит идеологии react.
Во-вторых пишите props в state в FruitsList только в конструкторе.
Ну и передаете несуществующий обработчик в onClick.

Исправленный вариант.
Изучайте, делайте выводы.
Ответ написан
miraage
@miraage
Почему люди никогда не читают документацию????

https://reactjs.org/docs/state-and-lifecycle.html#...

Do Not Modify State Directly

// EDIT

А prevState.fruitList.push("Мандаринка") по-вашему что? Это мутация в чистом её виде.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы