[英]How to call useContext in a function using react and typescript?
我已经为设置状态定义了如下上下文,如下所示,
interface DialogsCtxState {
isDialogOpen: boolean;
setIsDialogOpen: React.Dispatch<React.SetStateAction<boolean>>;
itemVisible: boolean;
setItemVisible: React.Dispatch<React.SetStateAction<boolean>>;
}
const initialState: DialogsCtxState = {
isDialogOpen: false,
setIsDialogOpen: () => {},
itemVisible: false,
setItemVisible: () => {},
};
export const DialogsContext = React.createContext<
DialogsCtxState
>(initialState);
export const DialogsContextProvider: React.FC = ({ children }) => {
const [isDialogOpen, setIsDialogOpen] = React.useState<boolean>(
false
);
const [itemsVisible, setItemsVisible] = React.useState<boolean>(
false
);
return (
<DialogsContext.Provider
value={{
isDialogOpen,
setIsDialogOpen,
itemVisible,
setItemVisible,
}}
>
{children}
</DialogsContext.Provider>
);
};
我在两个组件 Uploadbutton 和 userbutton 中使用这个上下文,如下所示,
function UploadButton() {
const {isDialogOpen, setIsDialogOpen, itemVisible, setItemVisible} =
React.useContext(DialogContext);
const onUpload = () => {
itemVisible && setItemVisible(false);
setIsDialogOpen(isDialogOpen => !isDialogOpen);
}
return (
<Button onClick={onUpload}/>
);
}
function UserButton() {
const {isDialogOpen, setIsDialogOpen, itemVisible, setItemVisible} =
React.useContext(DialogContext);
const onAdd = () => {
isDialogOpen && setIsDialogOpen(false);
setItemVisible(prev => !prev);
}
return (
<Button onClick={onAdd}/>
);
}
上面的代码片段工作正常。 但我想将带有 onUpload 和 onAdd 方法的代码移动到 DialogContext 文件,该文件的计算结果如下所示,
const onAdd = () => {
function1(); //where thiscontains the code in onAdd before snippet.
}
const onUpload = () => {
function2();//where this contains code in onUpload snippet before
}
我尝试过的,
在包含 DialogContext 的文件中,我尝试了类似下面的内容,
export const function1 = () => {
const {isDialogOpen, setIsDialogOpen, itemVisible, setItemVisible} =
React.useContext(DialogContext); //error here
isDialogOpen && setIsDialogOpen(false);
setItemVisible(prev => !prev);
}
export const function2 = () => {
const {isDialogOpen, setIsDialogOpen, itemVisible, setItemVisible} =
React.useContext(DialogContext); //error here
itemVisible && setItemVisible(false);
setIsDialogOpen(isDialogOpen => !isDialogOpen);
}
但是我得到错误 react.usecontext is used in a function 这既不是反应 function 组件也不是自定义反应钩子。
我怎样才能解决这个问题。 有人可以帮我解决这个问题。 谢谢。
看起来从上下文返回的值的唯一用途是创建onUpload
和onAdd
函数。 在DialogsContextProvider
组件中创建函数以将它们作为值传递将是一种更好的方法。 例子
// context
interface DialogsCtxState {
onUpload: () => void;
onAdd: () => void;
};
const initialState: DialogsCtxState = {
onUpload: () => {},
onAdd: () => {}
};
export const DialogsContext = React.createContext<
DialogsCtxState
>(initialState);
DialogsContextProvider
组件
// context provider
export const DialogsContextProvider: React.FC = ({ children }) => {
const [isDialogOpen, setIsDialogOpen] = React.useState<boolean>(
false
);
const [itemsVisible, setItemsVisible] = React.useState<boolean>(
false
);
// onUpload function
const onUpload = useCallback(() => {
itemsVisible && setItemsVisible(false);
setIsDialogOpen((isDialogOpen) => !isDialogOpen);
}, [itemsVisible]);
// onAdd function
const onAdd = useCallback(() => {
isDialogOpen && setIsDialogOpen(false);
setItemsVisible((prev) => !prev);
}, [isDialogOpen]);
return (
<DialogsContext.Provider value={{ onAdd, onUpload}}>
{children}
</DialogsContext.Provider>
);
};
这就是它在UploadButton
和UserButton
组件中的使用方式,
const UserButton: React.FC = () => {
const { onAdd } = React.useContext(DialogsContext)
// rest of the logic
}
const UploadButton: React.FC = () => {
const { onUpload } = React.useContext(DialogsContext)
// rest of the logic
}
注意您的代码中有多个拼写错误,因此如果我们忽略了在您采用自定义 function 方法时发生的错误,因为useContext
只能用于功能组件和自定义钩子。 要解决这个问题,您必须采用自定义挂钩方法。 例如
export const useOnUpload = () => {
const { isDialogOpen, setIsDialogOpen, itemsVisible, setItemsVisible,
} = React.useContext(DialogsContext);
const onUpload = useCallback(() => {
itemsVisible && setItemsVisible(false);
setIsDialogOpen((isDialogOpen) => !isDialogOpen);
}, [itemsVisible, setIsDialogOpen, setItemsVisible]);
return onUpload;
};
// usage
function UploadButton() {
const onUpload = useOnUpload();
// rest of the logic
}
// similarly you can create the onUseAdd hook
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.