![](/img/trans.png)
[英]How to use hooks as value of context provider in react js typescript
[英]How to properly use React Context Provider with Typescript?
我已經持續了好幾個小時試圖尋找我認為可行但無法做到的東西。 你能幫我解決這個問題嗎?
我在這里有我的文件瀏覽器上下文,我想將文件夾數據傳遞給另一個 function。
import { createContext, useContext } from 'react';
export interface fileBrowserContext {
folderData: string;
}
export const FileBrowserContext = createContext<fileBrowserContext>({
folderData: '',
});
export const useFileBrowserContext = () => useContext(FileBrowserContext);
這是我使用它的組件。 我還使用了 react-hook-form,當我單擊提交按鈕時它正在工作。
const FileBrowser = () => {
const { control, watch, handleSubmit, register, reset, errors } = useForm({
reValidateMode: 'onChange',
defaultValues: {
createFolder: '',
},
});
const [folderData, setFolderData] = useState<string>('');
async function onSubmit(formData: any) {
if (Object.keys(errors).length === 0) {
/* Create folder */
setFolderData(formData.createFolder);
reset({ createFolder: '' });
}
handleToastSuccess({
message: 'Folder Created',
});
}
function renderForm() {
return (
<Form onSubmit={handleSubmit(onSubmit)} className="CreateFolderForm">
<Form.Group>
<Form.Label>Create Folder</Form.Label>
<Form.Control
id="createFolder"
name="createFolder"
ref={register({
required: {
value: true,
message: 'This field is required.',
},
})}
/>
</Form.Group>
<Button
variant="contained"
color="primary"
type="submit"
>
Create
</Button>
</Form>
);
}
const {
isCreateFolderOpen,
setIsCreateFolderOpen,
handleFileCallback,
} = useFileActionHandler(
createFolder,
);
return (
<FileBrowserContext.Provider value={{ folderData: folderData }}>
<>
<h1> File Browser </h1>
{folderData + ','}
</>
<CustomModal
showModal={isCreateFolderOpen}
setShowModal={setIsCreateFolderOpen}
modalHeading="Create Folder"
modalContent={renderForm()}
/>
</FileBrowserContext.Provider>
)
}
我正在 utils.tsx 上調用我的 useFileBrowserContext()。 我需要上面組件中的 folderData,我打算在其中使用上下文調用該組件,以便能夠將文件夾保存在我正在使用的 Chonky 庫中。
export const useFileActionHandler = (
setCurrentFolderId: (folderId: string) => void,
createFolder: (folderName: string) => void,
) => {
const [isCreateFolderOpen, setIsCreateFolderOpen] = useState<boolean>(false);
const { folderData } = useFileBrowserContext();
const handleFileCallback = useCallback(
(data: ChonkyFileActionData) => {
if (data.id === ChonkyActions.CreateFolder.id) {
// CONTEXT BEING CALLED HERE
setIsCreateFolderOpen(true);
if (folderData) createFolder(folderData);
}
console.log('file browser', folderData);
},
[
createFolder,
],
);
return {
handleFileCallback,
isCreateFolderOpen,
setIsCreateFolderOpen,
};
};
我的控制台中沒有錯誤,但行為是當我在 utils.tsx 中控制台記錄 folderData 時,它返回一個空字符串,我認為這意味着從組件傳遞的 folderData 不起作用。 提前感謝您的幫助。
為了讓組件使用useContext
,它們必須是Context.Provider
的后代。 在您的情況下,您嘗試在FileBrowser
組件中使用FileBrowserContext
,但它不是Context.Provider
的后代,因此它接收folderData
的默認值(空字符串)。
所以,目前你有:
<App>
<FileBrowser>
<FileBrowserContext.Provider>
{/* ... */}
</FileBrowserContext.Provider>
</FileBrowser>
</App>
但你需要
<App>
<FileBrowserContext.Provider>
<FileBrowser>
{/* ... */}
</FileBrowser>
</FileBrowserContext.Provider>
</App>
解決方法是將您的Context.Provider
組件向上移動一個級別並將其呈現為FileBrowser
的父級,而不是讓FileBrowser
本身呈現它。 您可以將其包裝到一個自定義組件中,該組件處理設置正確的value
,如下所示:
const FileBrowserContextProvider = () => {
const [folderData, setFolderData] = useState('');
return (
<FileBrowserContext.Provider value={{ folderData, setFolderData }}>
{children}
</FileBrowserContext.Provider>
);
};
const App = () => {
return (
<FileBrowserContextProvider>
<FileBrowser /> {/* <-- now FileBrowser can safely useContext
since it's a descendent of the Provider */}
</FileBrowserContextProvider>
);
};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.