反应:更改功能组件中的状态也更改功能组件的props值及其父类状态

时间:2019-10-25 20:15:07

标签: javascript reactjs react-hooks setstate

如果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才应更新。

当前行为:功能组件状态更新后,类组件的this.state.list也将更新

1 个答案:

答案 0 :(得分:1)

您正在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);