【问题标题】:async/await in react functional component反应功能组件中的异步/等待
【发布时间】:2020-06-30 09:04:55
【问题描述】:

我正在做类似以下的事情

(https://stackoverflow.com/a/57847874/433570)

 const LowerCard = (props) => {

   let { review_meta, step } = props
   const [component, setComponent] = useState('');
   const {state, editDispatch} = useContext(ReviewMetaEditCardDispatch);

   useEffect(() => {

     // https://stackoverflow.com/a/57847874/433570

     const setDynamicComponent = async () => {
       let DynamicComponent
       switch(state.step) {
       case 'title':
         DynamicComponent = await import('review/react/components/review-meta-edit-card/step/title')
         break
       }

       if (DynamicComponent) {
         setComponent(DynamicComponent.default)
       }
     }

     setDynamicComponent()
   }, []);


   if (!component) {
     return null
   }

   return (
     <View>
       <component/>
     </View>
   )
   }

上面的代码有效,但是当我在useEffect 调用中删除[] 时,它会导致 index.js:1 Warning: Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. You can only call Hooks at the top level of your React function.

我猜它在抱怨你不应该在useEffect 中调用setComponent(这是一个钩子)。

我该如何克服这个问题?

【问题讨论】:

  • 哦,那我该如何运行上面的代码来实现等价的componentDidUpdate呢?
  • 我尝试添加 [state.step] 这是导致我更改组件的原因,但它仍然会产生相同的错误
  • 效果里面还有其他条件吗?什么时候重新运行?

标签: reactjs react-native async-await


【解决方案1】:

你不应该直接在 useEffect 中使用异步函数。

这是我的解决方案,看看它是否有效



const LowerCard = props => {
  let {review_meta, step} = props;
  const [component, setComponent] = useState('');
  const {state, editDispatch} = useContext(ReviewMetaEditCardDispatch);

  const setDynamicComponent = useCallback(async () => {
    let DynamicComponent;
    switch (state.step) {
      case 'title':
        DynamicComponent = await import('review/react/components/review-meta-edit-card/step/title');
        break;
    }

    if (DynamicComponent) {
      setComponent(DynamicComponent.default);
    }
  }, [state]);

  useEffect(() => {
    // https://stackoverflow.com/a/57847874/433570
    setDynamicComponent();
  }, [setDynamicComponent]);

  if (!component) {
    return null;
  }

  return (
    <View>
      <component />
    </View>
  );
};


【讨论】:

  • 试试{component} 而不是&lt;component/&gt;
  • JSX中的自定义组件名应该大写
【解决方案2】:

您的动态组件正在使用钩子,如果您调用 importedComponent.default,React 将抛出在 useEffect 内部使用钩子的错误错误。

相反,加载组件并在渲染时调用.default

我还添加了 state.stepuseEffect 依赖项数组,以确保在 state.step 发生变化时重新运行效果,就像在初始渲染 state.step 不是 title 组件将永远不会渲染因为您提供了一个空的依赖项数组

useEffect(() => {
  // same as before
  // ...
  if (DynamicComponent) {
    setComponent(DynamicComponent);
  }
}, [state.step])

if (!component) {
  return null;
}

return (
  <View>
    <component.default />
  </View>
)

【讨论】:

  • DynamicComponent.default 不是在调用它,而是在读取参考。在 useEffect 或 render 中附加 .default 没有区别
  • @Max 实际上确实会有所不同,如果你在 useEffect 中调用 DynamicComponent.default,React 会出错,因为它返回默认导出组件的结果
  • @Max codesandbox.io/s/peaceful-leaf-wdk6l 删除注释行,看看有什么不同,请务必注释其他行
  • 确实是因为*.default
  • @AsafAviv 我试过你的例子,它确实适用于setComponent(DynamicComponent)。但是我仍然不清楚为什么会发生这种情况,因为这里setComponent(DynamicComponent.default) 我们没有调用函数——调用它是setComponent(DynamicComponent.default())。当我有更多时间时,我会做一些额外的调查
猜你喜欢
  • 1970-01-01
  • 2019-04-22
  • 2019-05-18
  • 1970-01-01
  • 1970-01-01
  • 2019-07-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多