中间组件应该控制状态的部分并且调用道具传递给它们还是应该提升状态?我一直在来回询问是否让子组件使用本地状态,或者让它由更高的组件处理并传递额外的支持。
在这个有限的例子中,我有一个Main
组件。我在此组件中显示一些数据并传递函数以将数据过滤到子组件。但是,主要组件不一定需要知道menuOpen
属性何时更改。但是,我需要在调用menuOpen
,handleCancel()
和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>
);
};
答案 0 :(得分:0)
优化关注点的分离,我认为你会更喜欢它。
Filter
中定义所有复选框事件处理程序。 Filter
仅通过州与Main
进行通信。
Main
评估UI组件以设置状态。 Main
定义Filter
状态,以便根据需要使用以避免上述情况。Filter
将构建复选框。Cancel
和Save
按钮对我来说似乎是Filter
级功能。 FilterMenu
组件现在看起来毫无意义,因为它不会做任何事情。也许在较大的架构中,它很有用,但您可以在需要时始终将其从Filter
重新分解为Filter
组件是代码中用于将操作与状态分开的接缝。
Main
和Filter
之间的耦合减少了。 Filter
具有更多的重用潜力。