Реакция: Изменение состояния в функциональном компоненте также Изменение значения реквизита функционального компонента и его состояния родительского класса - PullRequest
0 голосов
/ 25 октября 2019

У меня есть родительский класс, скажем, Data, и я представляю модель со списком флажков, если this.state.showList имеет значение true, и передаю this.state.list в качестве реквизита для функционального компонента (см. Код)

ДанныеКомпонент класса

import React from "react";
import Model from "./components/Model";

class Data extends React.Component {
  state = {
    list: [
           {name:'ABC', selected: false},
           {name:'DEF', selected: false},
           {name:'GHI', selected: false},
           {name:'JKL', selected: false},
           {name:'MNO', selected: false},
          ],
    showList: false
  };

  toggleModel = () => {
    this.setState({
      showList: !this.state.showList 
    });
  };

  updateState= (list) => {
    this.setState({ list, showList: !this.state.showList });
  }

  render() {
    const model= this.state.showList ? (
      <Model
        Click={this.toggleModel}
        okayClick={this.updateState}
        list={this.state.list}
      />
    ) : null;
    return (
      <div className="container">
        {model}
        // Extra
      </div>
    );
  }
}
export default Data;

Функциональный компонент модели

import React, { useState, useEffect } from "react";
import Button from "./UI/Button/Button";

const FilterModel = (props) => {
  const [state, setState] = useState(props.list);

  const checkboxClick = (index, selected) => {
    const newState = [...state];
    const newElement = newState[index];
    newElement.selected = !selected;
    newState[index] = newElement;
    setState(newState);
  };

  return (  
    <div className="model_container" onClick={() => props.Click("")}>
      <div className="model" onClick={e => e.stopPropagation()}>
        <div className="model_head">
          <span className="title">List</span>
        </div>
        <div className="model_body">
          <ul>
            {state.map((currentElement, index) => (
              <li key={index}>
                <label>
                  <input
                    type="checkbox"
                    onChange={() =>
                      checkboxClick(index, currentElement.selected)
                    }
                    checked={currentElement.selected}
                  />
                  {currentElement.name}
                </label>
              </li>
            ))}
          </ul>
        </div>
        <div className="model_foot">
          <div className="button_container">
            <Button
              buttonType="default"
              text="Cancel"
              Click={() => props.Click("")}
            />
            <Button
              buttonType="default"
              text="Okay"
              Click={() => props.okayClick(state)}
            />
          </div>
        </div>
      </div>
    </div>
  );
};

export default Model;

Ожидаемое поведение: this.state.List компонента Class должен обновляться только при нажатии кнопки «ОК».

ТекущийПоведение: this.state.list компонента класса обновляется, как только состояние функционального компонента обновляется

1 Ответ

1 голос
/ 26 октября 2019

Вы меняете состояние здесь checkboxClick:

const newState = [...state]; // shallow clone of the state array, objects inside the array are not cloned
const newElement = newState[index]; // getting reference to the original object
newElement.selected = !selected; // mutating the original object
newState[index] = newElement; // replacing the original object reference with the original object reference does nothing

Пример:

const state = [{}];

const newState = [...state];
const newElement = newState[0];
newElement.selected = true;

console.log(state[0] === newElement);

Вам также необходимо клонировать изменяемый объект:

const state = [{}];

const newState = [...state];
const newElement = { ...newState[0] };
newElement.selected = true;

console.log(state[0] === newElement);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...