反应:在组件挂载之前从useEffect调用自定义钩子或运行代码

时间:2020-07-31 01:02:24

标签: reactjs

我什至都不愿意问这个,但是这里...

我有一个基于this implementation的自定义钩子useScript,但是我想从useEffect调用它,以便它在组件安装之前运行,但根据rules of hooks,我知道我可以做到这一点。

问题是我想延迟渲染我的组件,直到脚本加载完毕,但是我没有办法设置状态而不会导致“渲染次数过多”错误。

这是我尝试过的两个无效的选项:

  useEffect(() => {
    // Cannot call another hook from inside useEffect
    useScript('https://cdnjs.cloudflare.com/ajax/libs/typescript/3.9.7/typescript.min.js');
  }, []);

  const myComponent = (scripts) => {

    const [loaded, setLoaded] = useState(false);

    scripts.forEach(script => {
      useScript('https://cdnjs.cloudflare.com/ajax/libs/typescript/3.9.7/typescript.min.js');
    });

    // where can I call setLoaded ??

    return (loaded && <div>some content</div>);
  };

这应该很简单;我忘记了什么?

1 个答案:

答案 0 :(得分:1)

一种方法是让钩子返回执行某些功能的函数。

所以代替:

function useScript() {
  const [isLoaded, setIsLoaded] = useState(false);

  // load the script...

  return [isLoaded]
}

您可以这样做:

function useLoadScript() {
  const [isLoaded, setIsLoaded] = useState(false);

  const loadScript = () => {
    // load the script...
  }

  return [isLoaded, loadScript]
}

以便可以在另一个挂钩中使用该功能:

function MyComponent(props) {
  const [isLoaded, loadScript] = useLoadScript()
  
  useEffect(() => {
    loadScript()
    // ...
  }, [])

  if (!isLoaded) {
    return <p>Loading...</p>
  }

  return (
    // ...
  )
}