问题描述
我是 react-admin 的新手,我正在尝试构建自定义图片库输入。它应该显示一个带有图像的模式(数据已经被提取并存储在 redux 中),以便用户可以选择一个或多个图像(选择后,一个动作被调度来更新减速器的值),我需要这些选择的图像 ID 在转换中<Create />
上的函数,以便我可以在调用 dataProvider 方法之前添加所需的数据。
但我有一个奇怪的问题,这可能是因为我缺乏反应知识。在下面的代码段中,我尝试获取 useReducer
的值,然后将其添加到表单中。
import React,{ useReducer,useMemo,useEffect,useCallback } from 'react';
import { Create as Ra_create } from 'react-admin';
const ctxInitialValues = {};
const galleryCtx = React.createContext(ctxInitialValues);
const CreateWithgallery = (props) => {
const [selectedImages,dispatch] = useReducer((state,{ type,payload }) => {
switch (type) {
case 'UPDATE_STATE':
return { ...payload };
case 'INIT_RECORD':
return {
...state,[payload]: [],};
default:
return state;
}
},ctxInitialValues);
const updateSelection = (record,image,operation) => {
if (operation === 'add') {
let newState = {
...selectedImages,[record]: [...selectedImages[record],image],};
dispatch({
type: 'UPDATE_STATE',payload: newState,});
} else if (operation === 'remove') {
let newState = {
...selectedImages,[record]: selectedImages[record].filter((item) => item.id !== image.id),});
}
};
const transformPayload = (data) => {
let transformed = {
...data,};
// but I get {} here
for (let record in selectedImages) {
transformed[record] = selectedImages[record].map((item) => ({
id: item.id,}));
}
return transformed;
};
useEffect(() => {
console.log(selectedImages);
// I get fresh values here
},[selectedImages]);
const initializeRecord = (record) => {
dispatch({
type: 'INIT_RECORD',payload: record,});
};
return (
<galleryCtx.Provider
value={{
selectedImages,updateSelection,initializeRecord,}}
>
<Ra_create {...props} transform={transformPayload}>
{props.children}
</Ra_create>
</galleryCtx.Provider>
);
};
export { galleryCtx };
export default CreateWithgallery;
当我尝试访问转换函数中的 selectedImages 值时,我得到 {},这是初始状态。我曾尝试使用 useCallback 和 useMemo 来确保每次调度后更改值,但没有任何区别。 这个问题中也有类似的行为: React Admin: how to pass state to transform
如何在转换函数中使用状态?
解决方法
要解决此问题,您可以按照 react-admin docs 中的说明使用转换道具。仍然不清楚,为什么我们不能在 or 上的转换函数中获得状态。
,我最终在组件上设置了变换道具(在自定义工具栏中):
const CustomToolbar = (props: any) => {
const transform = useCallback((data: any) => {
return {
...data,files: something_from_state,};
},[something_from_state]);
const handleClick = () => {
};
return <Toolbar {...props}>
<SaveButton
handleSubmitWithRedirect={handleClick} transform={transform}/>
</Toolbar>
};