Reactjs 具有id字段的重复使用选择器
我需要你关于用选择器过滤数据的建议。假设我的应用程序中有以下实体。1组织有多个设备,在“我的状态”形状中显示如下:Reactjs 具有id字段的重复使用选择器,reactjs,redux,react-hooks,Reactjs,Redux,React Hooks,我需要你关于用选择器过滤数据的建议。假设我的应用程序中有以下实体。1组织有多个设备,在“我的状态”形状中显示如下: state { devices: { byId: [ 1 { name: device1 } ] } organizations: { byId: [ 1 { name: org1, devices: [1,2,3] } ] } } 现在我想过滤组织内部的设备。这是我想用选择器做的事情。我的
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))
}
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>
)
}
这应该可以正常工作,但是在我从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
}
}
})
我的功能组件如下所示:
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))
}
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>
)
}
功能设备(){
const dispatch=usedpatch();
常量设备=使用选择器(选择组织设备(1))
useffect(()=>{
调度(fetchOrganizationDevices(1))
}, [])
常量列=[]
返回(
)
}
我现在得到的错误是
organization.devices未定义
,表示状态中的设备数组为空。似乎在分派之前调用了useSelector。如何防止重复执行此操作?或者应该在我的代码中更改什么?是的,useffect
钩子在第一次渲染后运行<代码>使用选择器将在第一次渲染期间运行。因此,您的组件代码需要安全地处理数据还不存在的情况
另外,不要将硬编码的数组/对象文本放入这样的选择器中,因为它每次都是一个新引用,并在每次调度操作时强制组件重新渲染。将其提取到选择器外部的常量,或者使用诸如“重新选择”之类的记忆库来创建选择器
最后,您应该使用,其中包括简化几个常见Redux用例的实用程序,包括存储设置、定义缩减器、不可变更新逻辑,甚至一次创建整个状态“切片”。它还有一个新的
createEntityAdapter
API,可以帮助您管理商店中的规范化状态。试试return organization.devices?org.devices.map(id=>selectDevice(id)(state)):[]
我不知道createEntityAdapter
API。非常感谢你的支持和帮助!