【问题标题】:Redux useSelector with id field带有 id 字段的 Redux useSelector
【发布时间】:2020-10-17 22:40:03
【问题描述】:

我需要您对使用选择器过滤数据的建议。假设我的应用程序中有以下实体。 1 个组织有多个设备,在我的状态下看起来如下:

state {
   devices: {
       byId: [ 1 { name: device1 } ]
   }
   organizations: {
       byId: [ 
          1 { name: org1, devices: [1,2,3] } 
       ]
   }
}

现在我想过滤组织内的设备。这是我想用选择器做的事情。我的选择器如下所示:

const selectDevice = (id: any) => (state: State) => state.devices.byId[id]


export const selectOrganizationDevices = (id: number) => (state: State) => {
    const organization = state.organizations.byId[id] || []
    return organization.devices.map(id => selectDevice(id)(state))
}

这应该可以正常工作,但是在我从 redux 发送数据之前,我的选择器就被调用了。我想我的减速器或我创建的组件有问题。

我的减速器是这样的:

return produce(state, draftState => {
        switch (action.type) {
            ...
            case OrganizationActionTypes.FETCH_DEVICES_SUCCESS: {
                draftState.byId = action.payload.entities.organizations
                draftState.allIds = Object.keys(action.payload.entities.organizations)
                draftState.loading = false
                break;
            }
            ...
            default: {
                return state
            }
        }
    })

我的功能组件如下所示:

function Devices() {
    const dispatch = useDispatch();
    const devices = useSelector(selectOrganizationDevices(1))

    useEffect(() => {
        dispatch(fetchOrganizationDevices(1))
    }, [])

    const columns = []
    
    return (
        <Layout headerName={"Devices"}>
             <Table dataSource={devices} columns={columns}/>
        </Layout>
    )
}

我现在得到的错误是organization.devices is undefined,它表示处于状态的设备数组为空。似乎在调度之前调用了 useSelector 。如何防止 redux 这样做?或者我的代码应该改变什么?

【问题讨论】:

  • 试试return organization.devices ? organization.devices.map(id =&gt; selectDevice(id)(state)): []

标签: reactjs redux react-hooks


【解决方案1】:

是的,useEffect 钩子第一次渲染之后运行。 useSelector 将在第一次渲染期间运行。因此,您的组件代码需要安全地处理该数据尚不存在的情况。

另外,不要将硬编码的数组/对象字面量放在这样的选择器中,因为它每次都会是一个新的引用,并且每次调度操作时都会强制您的组件重新渲染。要么将其提取到选择器之外的常量,要么使用像 Reselect 这样的记忆库来创建选择器。

最后,您应该使用our official Redux Toolkit package,其中包含用于简化几个常见 Redux 用例的实用程序,包括存储设置、定义 reducer、不可变更新逻辑,甚至一次创建整个状态“切片”。它还有一个新的createEntityAdapter API,可帮助您管理商店中的规范化状态。

【讨论】:

  • 我不知道createEntityAdapter API。非常感谢您对我的支持!
猜你喜欢
  • 2020-08-18
  • 2018-09-08
  • 2019-12-14
  • 2020-05-17
  • 1970-01-01
  • 2021-06-12
  • 2021-09-03
  • 1970-01-01
  • 2019-12-19
相关资源
最近更新 更多