Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 在存储加载后使用选择器更新组件_Reactjs_Redux - Fatal编程技术网

Reactjs 在存储加载后使用选择器更新组件

Reactjs 在存储加载后使用选择器更新组件,reactjs,redux,Reactjs,Redux,目前,我在“布局”组件DidMount上初始化了相关的存储数据(库和片段)。此数据是从API获取的 const mapDispatchToProps = { GetRooms, GetPieces } class Layout extends React.Component { ... componentDidMount () { this.props.GetRooms() this.props.GetPieces() }

目前,我在“布局”组件DidMount上初始化了相关的存储数据(库和片段)。此数据是从API获取的

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
    };
}