【发布时间】:2018-03-17 14:53:18
【问题描述】:
在我的公司,我们正在将 Web 应用程序的前端迁移到 ReactJS。 我们正在使用 create-react-app(更新到 v16),没有 Redux。 现在我被困在一个可以通过下图简化结构的页面上:
三个组件(SearchableList、SelectableList 和 Map)显示的数据在 MainContainer 的componentDidMount() 方法中使用相同的后端请求检索。然后这个请求的结果被存储在 MainContainer 的状态中,并且具有或多或少这样的结构:
state.allData = {
left: {
data: [ ... ]
},
right: {
data: [ ... ],
pins: [ ... ]
}
}
LeftContainer 从 MainContainer 接收作为 prop state.allData.left 并将 props.left.data 传递给 SearchableList,再次作为 prop。
RightContainer 从 MainContainer 接收作为 prop state.allData.right 并将 props.right.data 传递给 SelectableList 和 props.right.pins 传递给 Map。
SelectableList 显示一个复选框以允许对其项目进行操作。每当在 SelectableList 组件的某个项目上发生操作时,它可能会对 Map 引脚产生副作用。
我决定在 RightContainer 的状态中存储一个列表,该列表保留 SelectableList 显示的所有项目的 id;此列表作为道具传递给 SelectableList 和 Map。然后我将一个回调传递给 SelectableList,每当进行选择时,都会更新 RightContainer 中的 id 列表;新的 props 到达 SelectableList 和 Map,因此在两个组件中都调用了 render()。
它工作正常,有助于将可能发生在 SelectableList 和 Map 上的所有事情保存在 RightContainer 中,但我想问这对于 lifting-state-up 和 single- 是否正确真相的来源 概念。
作为可行的替代方案,我想为 MainContainer 中 state.right.data 中的每个项目添加一个 _selected 属性,并将选择回调向下传递三个级别到 SelectableList,处理 MainContainer 中的所有可能操作。但是一旦选择事件发生,这最终将强制加载 LeftContainer 和 RightContainer,从而需要实现 shouldComponentUpdate() 之类的逻辑来避免无用的 render(),尤其是在 LeftContainer 中。
从架构和性能的角度来看,哪个/可能是优化此页面的最佳解决方案?
下面是我的组件的摘录,以帮助您了解情况。
MainContainer.js
class MainContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
allData: {}
};
}
componentDidMount() {
fetch( ... )
.then((res) => {
this.setState({
allData: res
});
});
}
render() {
return (
<div className="main-container">
<LeftContainer left={state.allData.left} />
<RightContainer right={state.allData.right} />
</div>
);
}
}
export default MainContainer;
RightContainer.js
class RightContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
selectedItems: [ ... ]
};
}
onDataSelection(e) {
const itemId = e.target.id;
// ... handle itemId and selectedItems ...
}
render() {
return (
<div className="main-container">
<SelectableList
data={props.right.data}
onDataSelection={e => this.onDataSelection(e)}
selectedItems={this.state.selectedItems}
/>
<Map
pins={props.right.pins}
selectedItems={this.state.selectedItems}
/>
</div>
);
}
}
export default RightContainer;
提前致谢!
【问题讨论】:
-
如果
RightContainer组件之外的其他组件不应该知道这些更改,那么我认为没有必要在更高级别的组件中管理此类数据。作为一般规则,当我不使用redux时,我会在所有需要特定数据的组件的父级管理数据状态。
标签: javascript reactjs create-react-app