Reactjs 在存储加载后使用选择器更新组件
目前,我在“布局”组件DidMount上初始化了相关的存储数据(库和片段)。此数据是从API获取的Reactjs 在存储加载后使用选择器更新组件,reactjs,redux,Reactjs,Redux,目前,我在“布局”组件DidMount上初始化了相关的存储数据(库和片段)。此数据是从API获取的 const mapDispatchToProps = { GetRooms, GetPieces } class Layout extends React.Component { ... componentDidMount () { this.props.GetRooms() this.props.GetPieces() }
const mapDispatchToProps = {
GetRooms,
GetPieces
}
class Layout extends React.Component {
...
componentDidMount () {
this.props.GetRooms()
this.props.GetPieces()
}
...
render () {
return (
...
<Route path="/Gallery/:roomName" component={Gallery} />
...
)
}
}
const mapDispatchToProps={
会议室,
拼凑
}
类布局扩展了React.Component{
...
组件安装(){
this.props.GetRooms()
this.props.GetPieces()
}
...
渲染(){
返回(
...
...
)
}
}
我有一个单独的“图库”组件,它通过布局组件内的react路由器路由加载。Gallery的mapStateToProps使用选择器功能过滤请求的Gallery对象,并附加包含相关工件对象数组的属性
const GetRoomByName = (state, roomName) => {
const room = state.rooms.all.find(room =>
room.Name === roomName
)
if (!room) return
room.Pieces = state.pieces.all.filter(piece =>
piece.RoomId === room.Id
)
return room
}
const mapStateToProps = (state, { match }) => ({
room: GetRoomByName(state, decodeURIComponent(match.params.roomName))
})
class Gallery extends React.Component {
...
render () {
const { room } = this.props
if (room === undefined) return <h3>Loading...</h3>
return (
...
{room.Pieces.map(piece =>
...
)}
...
)
}
}
const GetRoomByName=(state,roomName)=>{
constroom=state.rooms.all.find(房间=>
room.Name==roomName
)
如果(!房间)返回
room.Pieces=state.Pieces.all.filter(piece=>
工件.RoomId==房间.Id
)
休息室
}
常量mapStateToProps=(状态,{match})=>({
room:GetRoomByName(状态,decodeURIComponent(match.params.roomName))
})
类库扩展了React.Component{
...
渲染(){
const{room}=this.props
如果(房间===未定义)返回加载。。。
返回(
...
{room.Pieces.map(piece=>
...
)}
...
)
}
}
当我从主页导航到此页面时,存储已经初始化,选择器正确执行
但是,如果加载“Gallery”组件的路由被刷新或直接从地址栏加载,则数据尚未出现在存储中,并且在加载组件时,该组件不会更新。我可以运行控制台日志并渲染房间对象,但Pieces属性在加载到存储时不会触发重新渲染
感谢您的帮助问题与
连接
功能如何确定组件是否应重新加载有关<代码>连接仅当MapStateTrops
中的一个属性发生更改时(通过浅层比较确定),才重新启用组件。因为它使用浅层比较,所以组件不会重新加载,除非GetRoomByName
返回的引用发生更改。要解决这个问题,您应该从GetRoomByName
返回一个新对象,而不是修改状态中存在的对象(这可能会导致其他had也需要诊断问题)
但这并不是很有效,因为它每次都会返回一个新对象,导致组件重新渲染的频率比需要的更高。根据您的情况,这可能不是问题。如果是,您应该查看,它将缓存GetRoomByName
的结果
另外,从主页导航时代码起作用的原因是,您从
GetRoomByName
返回了不同的引用,因为roomName
发生了变化。谢谢!成功了。真不敢相信我竟然没有意识到。因此,关键在于对重播进行肤浅的比较。没问题!如果你以前没有见过,那么这不是最明显的诊断问题。你是对的,关键在于肤浅的比较。connect功能的操作与React pure组件类似。一旦你习惯了它,它实际上是一个主要的性能特性。我的经验法则是避免突变,因为它们会产生意想不到的副作用,而是利用不可变的替代品。
const GetRoomByName = (state, roomName) => {
const room = state.rooms.all.find(room =>
room.Name === roomName
);
if (!room) return
const pieces = state.pieces.all.filter(piece =>
piece.RoomId === room.Id
);
return {
...room,
Pieces: pieces
};
}