在React中,国家应该升多高?

时间:2018-05-08 23:47:11

标签: javascript reactjs

中间组件应该控制状态的部分并且调用道具传递给它们还是应该提升状态?我一直在来回询问是否让子组件使用本地状态,或者让它由更高的组件处理并传递额外的支持。

在这个有限的例子中,我有一个Main组件。我在此组件中显示一些数据并传递函数以将数据过滤到子组件。但是,主要组件不一定需要知道menuOpen属性何时更改。但是,我需要在调用menuOpenhandleCancel()handleSave()时更新handleButtonClick()

handleCancel()handleSave()都会修改显示的数据,因此我在Main组件中声明它们。

我应该从props组件传递所有这些Main还是使用中间组件来处理本地状态的较小部分,还要从父(祖父母等)组件调用props

主要组件

//Parent component
class Main extends React.Component {
  constructor() {
    super();
    this.state = {
      checkBoxes: {
        1: {
          name: 'Apple',
          isChecked: true,
        },
        //...
      },
      fruit: {
        1: {
          name: 'Apple',
        },
        //...
      },
      checkedBoxes: [],
    };

    this.baseState = JSON.stringify(this.state.checkBoxes);
    this.fruitFilter = this.fruitFilter.bind(this);
    this.handleSave = this.handleSave.bind(this);
    this.handleChange = this.handleChange.bind(this);
    this.resetState = this.resetState.bind(this);
  }

  resetState() {
    this.setState({checkBoxes: JSON.parse(this.baseState)});
  }

  //populates the checkedboxs array with name to filter by
  handleSave() {
    const checkedBoxes = Object.keys(this.state.checkBoxes)
      .filter(key => {
        //....some logic 
      });

    this.baseState = JSON.stringify(this.state.checkBoxes);
    this.setState({checkedBoxes: checkedBoxes});
  }

  //handles the checkbox toggle
  handleChange(e) {
    const checkBoxes = {...this.state.checkBoxes};
    checkBoxes[e.target.id].isChecked = e.target.checked;
    this.setState({checkBoxes: checkBoxes});
  }

  //filteres the fruit - if nothing is checked return them all
  fruitFilter(fruit) {
    return Object.keys(fruit)
      .filter(key => {
        //...filter logic 
      })
  }

  render() {
    const visibleFruits = this.fruitFilter(this.state.fruit);
    return (
      <div>
        <Filter
          resetState={this.resetState}
          checkBoxes={this.state.checkBoxes}
          handleSave={this.handleSave}
          handleChange={this.handleChange}
        />
        <div>
          <h2>Filtered Fruit</h2>
          {Object.keys(visibleFruits).map(key => {
            return (
              //... renders list of fruit
            );
          })}
        </div>
      </div>
    );
  }
}

子组件

class Filter extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      menoOpen: false,
    };

    this.handleCancel = this.handleCancel.bind(this);
    this.handleSave = this.handleSave.bind(this);
    this.handleButtonClick = this.handleButtonClick.bind(this);
  }

  handleSave() {
    this.setState({menuOpen: false});
    this.props.handleSave();
  }

  handleCancel() {
    this.setState({menuOpen: false});
    this.props.resetState();
  }

  handleButtonClick() {
    this.setState({menuOpen: !this.state.menuOpen});
  }

  render() {
    return (
      <div>
        <button onClick={this.handleButtonClick}>Choose Fruits</button>
        {this.state.menuOpen && (
          <FilterMenu
            checkBoxes={this.props.checkBoxes}
            handleSave={this.handleSave}
            handleCancel={this.handleCancel}
            handleChange={this.props.handleChange}
          />
        )}
      </div>
    );
  }
}

孙子组件

const FilterMenu = ({checkBoxes, handleChange, handleCancel, handleSave}) => {
  return (
    <div>
      {Object.keys(checkBoxes).map(key => {
        return (
          //... renders dropdown menu
        );
      })}
      <button onClick={handleCancel}>Cancel</button>
      <button onClick={handleSave}>Save</button>
    </div>
  );
};

1 个答案:

答案 0 :(得分:0)

优化关注点的分离,我认为你会更喜欢它。

  • Filter中定义所有复选框事件处理程序。
  • Filter仅通过州与Main进行通信。
    • 不要强制Main评估UI组件以设置状态。
    • Main定义Filter状态,以便根据需要使用以避免上述情况。
  • Filter将构建复选框。
  • CancelSave按钮对我来说似乎是Filter级功能。
  • FilterMenu组件现在看起来毫无意义,因为它不会任何事情。也许在较大的架构中,它很有用,但您可以在需要时始终将其从Filter重新分解为
  • Filter组件是代码中用于将操作与状态分开的接缝。
    • 国家不会被不必要地推下去。
    • 不会不必要地推动实际功能。
    • MainFilter之间的耦合减少了。 Filter具有更多的重用潜力。