我正在使用挂钩在我的应用程序中获取数据。钩子看起来像这样:
const initialState = {
response: null,
loading: true,
error: null
}
const useGetFetch(url, token, user, parser) => {
const [state, dispatch] = useReducer(fetchReducer, initialState)
useEffect (() => {
if(user){
fetch(...)
.then((data)=> data.json())
.then(dispatch(...)) // setting the state here
.catch((error) => dispatch(...)) // set error state
}
}, [user])
return [state.response, state.loading, state.error]
}
具体来说,我在表单组件内部使用此钩子,以获取一些数据以用作select元素内的选项。
但是,我需要能够让用户即时添加新选项。为方便起见,我在select元素旁边创建了一个按钮。如果用户按下此按钮,将弹出一个模态,并显示另一种形式,可以创建一个新选项。这个新选项通过发布请求发送到服务器,如果成功,则模式关闭。
我面临的问题是,模式关闭后,除非刷新页面,否则无法更新使用自定义数据获取挂钩获取的初始数据。有没有一种方法可以使这种情况在不触发页面刷新的情况下发生?
我最初的直觉是使用回调函数并将其传递到useGetFetch
并将其绑定到useEffect
钩子。然后,我可以将其传递给模式中的表单,并在成功提交后调用该函数,但这没有用。
我正在寻找的另一个选项是useCallback
钩子,但是我目前对它的了解还不够,无法知道它是否会有所帮助。
编辑
具体地说,我所做的是在父组件外部创建一个触发函数:
const trigger = () => console.log("click")
将其绑定到提取钩子上
const useGetFetch(url, token, user, parser, trigger) => {
const [state, dispatch] = useReducer(fetchReducer, initialState)
useEffect (() => {
if(user){
fetch(...)
.then((data)=> data.json())
.then(dispatch(...)) // setting the state here
.catch((error) => dispatch(...)) // set error state
}
}, [user, trigger])
return [state.response, state.loading, state.error]
}
并将其传递给父组件内的子组件:
const trigger = () => console.log("click")
const Parent = () => {
// load a bunch of stuff
// ...
const { show, toggle } = useModal()
const [optionsData, Loading, Error] = useGetFetch(
optionsUrl,
token,
user,
parser,
trigger
)
// ...
return (
<div>
{// ...}
<button
onClick={(e) => {
e.preventDefault()
toggle()
}}
>
Add
</button>
<Modal show={show} toggle={toggle}>
<ModalForm
show={show}
toggle={toggle}
trigger={trigger}
></ModalForm>
</Modal>
{// ...}
<div>
)
}
内部ModalForm
触发器在执行成功的发布请求后被调用。关闭模态后,不会更新数据。我的猜测是,在ModalForm
内调用触发器会在useEffect
内触发useGetFetch
,但似乎不起作用。
答案 0 :(得分:2)
如果清楚地理解了您的问题,我认为您要尝试的是在用户关闭模态时强制重新引用。
您可以通过触发useGetFetch
挂钩内的强制重新渲染来实现此目的,如下所示:
const useGetFetch(url, token, user, parser) => {
const [state, dispatch] = useReducer(fetchReducer, initialState)
// calling refetch will force a rerender on the hook
const [shouldRefetch, refetch] = useState({});
useEffect (() => {
if(user){
fetch(...)
.then((data)=> data.json())
.then(dispatch(...)) // setting the state here
.catch((error) => dispatch(...)) // set error state
}
}, [user, shouldRefetch]); // note the dep array
// returning the refetch functions so we can call the refetch() on modal close.
return [state.response, state.loading, state.error, refetch];
}
多数民众赞成在useGetFetch,现在,您将像这样使用钩子:-
const Parent = () => {
const { show, toggle } = useModal();
// notice the refetch method
const [optionsData, Loading, Error, refetch] = useGetFetch(
optionsUrl,
token,
user,
parser
);
return (
<div>
<button
onClick={e => {
e.preventDefault();
toggle();
}}
>
Add
</button>
<Modal show={show} toggle={toggle}>
<ModalForm
show={show}
toggle={toggle}
trigger={() => {
// probably onClose would be better name instead of `trigger`
// calling the refetch method with empty object, this will cause rerender
refetch({});
}}
></ModalForm>
</Modal>
</div>
);
};
答案 1 :(得分:0)
我认为您在useEffect函数中缺少,
,这就是为什么您获得X不是函数错误
useEffect (() => {
if(user){
fetch(...)
.then((data)=> data.json())
.then(dispatch(...)) // setting the state here
.catch((error) => dispatch(...)) // set error state
}
//comma here
},[user]);