在回调中使用钩子的解决方法 [英] Workaround to using hooks inside callbacks

查看:29
本文介绍了在回调中使用钩子的解决方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 redux 商店中有一些元素,我正在等待来自 API 的响应或已经收到响应.

I have in the redux store, some elements which I am either waiting for response form an API or have already received the response.

我想创建一个钩子,以免在我需要执行此操作的每个组件中重复逻辑.

I had the idea of creating a hook as to not repeat the logic in every component in which I need to do this.

当然,我收到了无法在回调中使用钩子的错误

But of course I am getting an error of not being able to use hooks inside callbacks

用例是这样的:假设我从 API1 接收字母.对于我从 API1 收到的每封信函,我都必须调用 API2 以获取有关该信函的更多详细信息,因此我想首先检查我是否已经向 API2 提出了这封特定信函的请求,如果没有,做到了.

The use case is like this: Suppose I receive alphabet letters from an API1. For each letter I have received from the API1, I have to make a call to API2 to get more details on that letter, so I want to check first if I have already made the request to API2 for this particular letter, and if not, make it.

为了简化,我将省略调用 API2 但响应尚未到达的情况.

To simplify, I will omit the case where the call was made to API2 but the response has not yet arrived.

这是我的钩子

useDetails = (letter) => {
  const dispatch = useDispatch()
  const { lettersDetails } = useSelector(state => ({
    lettersDetails: state.api2.lettersDetails
  }));

  const [details, setDetails] = useState('')

  useEffect(() => {
    if (letter) {      
      // See of I already have details for this letter 
      const letterDetails = _.find(lettersDetails, function(o) { return o.letter === letter; });
      if (!letterDetails) {
        dispatch(getLetterDetailsAction(letter))        
      } else {
        setDetails(`The place of ${letterDetails.letter} in the alphabet is ${letterDetails.position}`)
      }
    }
  }, [lettersDetails]);

  return details;
}

现在在我的组件中,我正在接收来自另一个 api api1 的信件,并用它们创建一个数组

In my component now, I am receiving letters from another api, api1, and creating a array with them

我想做的是对我收到的每封信使用如下钩子,但我不能.有什么替代方案?

What I would like to do is for each letter I receive use the hook as follows, but I can't. What alternative is there?

export default () => {      
  const { letters } = useSelector(state => ({
    letters: state.api1.letters // this is an array 
  }));
  const [mappedLetters, setMappedLetters] = useState([])


  useEffect(() => {

    setMappedLetters(letters.map(letter => { 
      return {
        letter,
        description: useDetails(letter) // here i want the return value from the hook
      }
    }))    
}, [letters])

问题是这个逻辑需要在多个组件中重复

The thing is this logic needs to be repeated across several components

非常感谢

推荐答案

您可以从自定义钩子返回值的访问器而不是值本身:

You can return an accessor to the value instead of the value itself from your custom hook:

// hook
function useDetails() {
  const dispatch = useDispatch()
  const [details, setDetails] = useState('')
  const { lettersDetails } = useSelector( ... )

  return useCallback((letter) => {
    // have access to letter & lettersDetails
    const letterDetails = // ...
    if (!letterDetails)
      dispatch( ... )
    else
      setDetails(letterDetails)
    return details
  }, [lettersDetails])
}

// component
export default () => {
  // ...
  const getLetter = useDetails()
  useEffect(() => {
     const description = getLetter(letter)
     // ...
  }, [letters])
}

这篇关于在回调中使用钩子的解决方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆