在我公司,我们正在将Web应用程序的前端迁移到ReactJS。我们正在使用create-react-
app(更新为v16),而没有Redux。现在,我停留在一个页面上,该页面可以通过以下图像进行简化:
在componentDidMount()
MainContainer方法中,使用相同的后端请求检索由三个组件(SearchableList,SelectableList和Map)显示的数据。然后,此请求的结果存储在MainContainer的状态中,其结构大致如下:
state.allData = {
left: {
data: [ ... ]
},
right: {
data: [ ... ],
pins: [ ... ]
}
}
LeftContainer state.allData.left
从MainContainer
接收作为道具,并props.left.data
再次作为道具传递到SearchableList。
RightContainer state.allData.right
从MainContainer
接收作为道具,并传递props.right.data
到SelectableList和props.right.pins
Map。
SelectableList显示一个复选框,允许对其项目执行操作。每当对SelectableList组件的一项操作发生时,它可能会对Map引脚产生副作用。
我决定在RightContainer状态下存储一个列表,该列表保留SelectableList显示的所有项目ID。此列表作为道具传递给SelectableList和Map。然后,我向SelectableList传递一个回调,该回调使每当进行选择时都会更新RightContainer中的ID列表;新道具同时出现在SelectableList和Map中,因此render()
在这两个组件中都被称为。
它工作得很好,有助于将Rightable容器中的SelectableList和Map可能发生的所有事情都保留在RightContainer中,但是我想问这对于
提升状态 和 事实真相的 概念是否正确。
作为可行的替代方案,我想到了向MainContainer中的_selected
每个项目添加一个属性,state.right.data
然后将select回调三级传递给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;
提前致谢!
如React文档所述
通常,几个组件需要反映相同的变化数据。我们建议将共享状态提升到最接近的共同祖先。
对于React应用程序中发生的任何数据更改,应该只有一个“事实来源”。通常,首先将状态添加到需要呈现的组件。然后,如果还需要其他组件,则可以将其提升到最接近的共同祖先。与其尝试在不同组件之间同步状态,不如依靠自上而下的数据流。
与双向绑定方法相比,解除状态涉及编写更多的“样板”代码,但这样做的好处是,查找和隔离错误的工作量较小。由于任何状态都“存在”于某个组件中,并且该组件本身可以更改它,因此,大大减少了错误的表面积。此外,您可以实现任何自定义逻辑来拒绝或转换用户输入。
因此,从根本上讲,您还需要将树状结构提升到正在被兄弟姐妹组件使用的状态。因此,您第selectedItems
一个将状态存储为状态的实现RightContainer
是完全合理的,这是一个很好的方法,因为父级不需要了解信息,并且这data
是由的两个child
组件共享的,而这两个组件RightContainer
现在只有一个来源真相。
根据您的问题:
作为可行的替代方案,我想到了将_selected属性添加到中的每个项目
state.right.data
,MainContainer
并将select回调传递到下三个级别,以SelectableList
处理in中的所有可能的操作MainContainer
我不同意这是比第一种更好的方法,因为您MainContainer
不需要知道selectedItems
或处理程序的任何更新。MainContainer
对这些州没有做任何事情,只是将其传承下去。
考虑到optimise on performance
您自己谈论实现a的问题shouldComponentUpdate
,但可以通过扩展组件来避免这种情况,方法是扩展React.PureComponent
和本质上shouldComponentUpdate
使用and
shallow
比较实现。state``props
根据文档:
如果您的React组件的
render()
函数在相同的道具和状态下呈现相同的结果,则React.PureComponen
在某些情况下可以使用t提高性能。
但是,如果多个深度嵌套的组件正在使用同一数据,则使用redux并将该数据存储在redux状态是有意义的。这样,整个应用程序就可以全局访问它,并且可以在不直接相关的组件之间共享它。
例如考虑以下情况
const App = () => {
<Router>
<Route path="/" component={Home}/>
<Route path="/mypage" component={MyComp}/>
</Router>
}
现在,如果Home和MyComp都想访问相同的数据。您可以通过render
prop 调用它们,将数据作为来自prop的prop
传递。但是,可以通过使用以下connect
函数将这两个组件都连接到Redux状态来轻松实现
const mapStateToProps = (state) => {
return {
data: state.data
}
}
export connect(mapStateToProps)(Home);
和类似的MyComp
。易于配置操作以更新相关信息
同样,为您的应用程序配置Redux特别容易,您将能够在单个化简器中存储与相同内容相关的数据。这样,您还可以模块化您的应用程序数据
HTTP协议是无状态的:每次请求都是一次新的请求,不会记得之前通信的状态 客户端与服务器端的一次通信,就是一次会话 实现状态保持的方式:在客户端或服务器端存储与会话有关的数据 存储方式包括cookie、session,会话一般指session对象 使用cookie,所有数据存储在客户端,注意不要存储敏感信息 推荐使用sesison方式,所有数据存储在服务器端,在客户端cookie中存储sessio
选择无状态滑动窗口操作的一些注意事项是什么(例如,通过updateStateByKey或新mapStateByKey)选择保持状态(例如通过updateStateByKey或新mapStateByKey)时,使用火花流处理连续的有限事件会话流? 例如,考虑以下场景: 一种可穿戴设备跟踪由穿戴者进行的体育锻炼。该装置自动检测何时开始锻炼,并发出信息;在锻炼过程中发出附加信息(如心率);最后,当练习完
问题内容: 我试图了解React的有状态和无状态组件之间的确切区别。好的,无状态组件只会做某事,但是什么也不会记住,而有状态组件可能会做同样的事情,但是它们会记住其中的内容。那是理论。 但是现在,在检查如何使用代码显示此内容时,我有点麻烦了。以下两个示例对吗?唯一的区别确实是函数的定义。 无状态组件的示例: 有状态组件的示例: 问题答案: 是的,那是有区别的。除了有 状态 组件,您还可以使用以下方
我遇到了一个关于TCP套接字保持活动的问题。 TCP keep alive在套接字连接后启用和配置,系统有自己的TCP keep alive配置。 “ss-to”可以显示连接的保持活动信息。 网络接口是一个PPPOE设备,如果我们打开接口,它将获得一个新的ip地址。旧的传输控制协议将一直建立到保活超时。 但有时“ss-to”显示tcp连接变成了“持久化”,这需要很长时间(大约15分钟)才能关闭。
如果我打开活动,复选框始终保持选中状态,即使我取消选中它并离开活动或关闭应用程序,在重新启动活动后,它也将保持选中状态。 我已尝试使用以下代码段保存活动的状态。 复选框应始终处于用户离开它的状态(选中或未选中)。
问题内容: 我在当前的项目中使用它来处理客户端身份验证等。当前它仅打印出客户端地址/端口,以便我可以检查一个TCP连接是否用于多个请求()或是否有新连接为每个请求建立(因此每次都会进行新的SSL握手)。当我使用FireFox对服务器发出多个请求时,我可以看到keep- alive正在运行。因此服务器部分可以很好地处理GET和POST请求。 如果我过去对服务器发出请求(在这种情况下, 不 使用SSL