简体   繁体   English

调用自定义钩子时无效的钩子调用

[英]Invalid Hook Call when calling a custom hook

I've been trying to solve a problem for 4 days and I've searched and searched a lot!我一直在尝试解决一个问题 4 天,我已经搜索了很多次! I'm not sure if I'm just searching for the wrong thing or seeing it and am just completely oblivious to it.我不确定我是否只是在寻找错误的东西或看到它并且完全没有注意到它。 My problem is that when I call the hook from the main function, it works, but when I call it via an onSubmit function, it fails for invalid hook call.我的问题是,当我从主函数调用钩子时,它可以工作,但是当我通过 onSubmit 函数调用它时,它会因无效的钩子调用而失败。 I understand the concept of why the hook would be invalid, but am just completely unsure how to resolve it.我理解为什么钩子无效的概念,但我完全不确定如何解决它。 I reformatted my hook so that I could initialize it earlier in my code and then call it via the onSubmit, but the problem is that the state token only gets updated on initialization and not whenever it's changed.我重新格式化了我的钩子,以便我可以在我的代码中更早地初始化它,然后通过 onSubmit 调用它,但问题是状态令牌只在初始化时更新,而不是在它改变时更新。 Thus leading to some API calls with a bad token.从而导致一些带有错误令牌的 API 调用。 Any Help Anyone can offer will be greatly appreciated!任何人都可以提供的任何帮助将不胜感激!

The Setup: NextJS, React-Form, Redux via Next-Redux-Wrapper, SWR设置:NextJS、React-Form、Redux 通过 Next-Redux-Wrapper、SWR

When ReactForm validates the form, I'd like for it to submit it's data to a custom hook.当 ReactForm 验证表单时,我希望它将其数据提交给自定义钩子。 However, that custom hook fails with the Invalid Hook Call.但是,该自定义钩子因无效钩子调用而失败。 It does it as soon as I defined a variable for useState.一旦我为 useState 定义了一个变量,它就会这样做。

-- Form Code --- -- 表格代码 ---

const { register, errors, handleSubmit, setValue, reset, control } = useForm()
<form onSubmit={ handleSubmit(onSubmit) }>

-- onSubmit Code --- -- 提交代码 ---

const onSubmit = (data) => {
   const newData = useApiPost(`users/update/${ id }`, submitData)
}

-- Custom Hook -- -- 自定义挂钩 --

function useApiPut(resource, params){
   const [ data, setData ] = useState(null)
   const [ error, setError ] = useState(null)

   const { url, data : inData } = rest(resource, params)

   //Post data
   const { data : resData, error : resError, mutate } = useSWR(
      state.user.token ? url : null,
      url => axios.request({
            url,
            method : 'post',
            data : inData,
            headers : { Authorization : `Bearer ${ state.user.token }` }
         })
         .then(({ data }) => data),
      { revalidateOnFocus : false }
   )

   useEffect(() => {
      if(resData) {
         setData(resData)
      }
      if(resError) {
         setError(resError)
      }
   }, [ resData, resError ])

   return { data, error, mutate }
}

So the answer to this ended up being a few different things.所以这个问题的答案最终是一些不同的事情。

First, accessing my store value via store.getState() resolved one issue with hooks.首先,通过 store.getState() 访问我的 store 值解决了一个钩子问题。

Secondly, moving away from SWR.其次,远离SWR。 It is an AWESOME wrapper and capable of a TON, no doubt.毫无疑问,它是一个很棒的包装器,并且具有 TON 的能力。 I just kept struggling with it and finally gave up.我只是一直在挣扎,最后放弃了。 I moved to using Axios Interceptors and it has been amazing.我转而使用 Axios Interceptors,这真是太棒了。 Axios doesn't cache (out of the box) like SWR, but I was utilizing the caching for tokens, so I wasn't really using it to it's full potential. Axios 不像 SWR 那样缓存(开箱即用),但我使用了令牌缓存,所以我并没有真正利用它的全部潜力。 Please note, I'm in no way bashing SWR, it's a really great and extremely powerful library.请注意,我绝不抨击 SWR,它是一个非常棒且极其强大的库。

Lastly, wrapping the entire set of hooks into one function allowed me to initialize the function at the root of my page and then access the hooks I needed to use later.最后,将整个钩子集包装成一个函数允许我在页面的根部初始化该函数,然后访问我稍后需要使用的钩子。

So instead of just calling useApiPost() now my hook looks like this:所以现在我的钩子看起来像这样,而不是仅仅调用 useApiPost():

const useApi = async() => {
   const post = async() => {
      //Do work here
   }
   return { post }
}

export default useApi

Then it's called like this inside the main function:然后在主函数中这样调用:

const { post } = useApi()

And it's called like this in the onSubmit Function:它在 onSubmit 函数中是这样调用的:

const options = await post(resource, params)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM