将 class 组件转换为函数组件时出错

Error converting class component to function component

我正在尝试将 class 组件转换为功能组件。

Class 组件:classBasedComponent.js [此文件中包含的原始代码]

我的进步:

功能组件:functionComponent.js[我的进度]

这里是GitHublink供参考:https://github.com/codebushi/gatsby-starter-dimension

这是我的错误:

我仍然遇到错误。我可以在哪里即兴创作?

让我们关注错误。

27:11 error 'timeoutId' is not defined no-undef

您将此变量声明为 timeoutId,但在引用它时在 timeoutIdtimeOutId 之间切换。在您当前的沙箱中,它是 timeoutId,因此所有 timeOutId 用法都被标记为未声明。选择其中之一并保持一致。

45:30 error 'setWrapperRef' is not defined no-undef

80:28 error 'setWrapperRef' is not defined no-undef

这看起来是由 Main 调用的一个函数,用于传回对 某个东西 的引用,然后在 handleClickOutside 中引用它。使用 react ref 来存储值。

const wrapperRef = React.useRef(null); // create ref to store value

...

const setWrapperRef = node => wrapperRef.current = node; // set current ref value

...

const handleClickOutside = (event) => {
  if (!wrapperRef.current.contains(event.target)) { // access current ref value
    if (isArticleVisible) {
      handleCloseArticle();
    }
  }
}

...

<Main
  isArticleVisible={isArticleVisible}
  timeout={timeout}
  articleTimeout={articleTimeout}
  article={article}
  onCloseArticle={handleCloseArticle}
  setWrapperRef={setWrapperRef} // attach ref value updater
/>

66:23 error Unexpected use of 'location' no-restricted-globals

location 之前是通过 props 收到的,它很可能仍然是通过 props.

收到的
<Layout location={props.location}>

或者因为我在您的功能组件中没有看到对 props 的其他引用,只需在组件签名中对其进行解构即可。如果你需要访问更多的 prop 值,你也可以在这里简单地解构它们。

function IndexPage({ location }) { ...

现在是警告

12:19 warning 'setArticle' is assigned a value but never used no-unused-vars

这只是意味着它被定义并且从未使用过,但是在检查基于 class 的组件时,更新 article 值发生在 handleOpenArticlehandleCloseArticle 中.因此,让我们在您的功能组件中做同样的事情。

这里的问题是您将额外的参数传递给 setIsArticleVisible 更新程序,但这些参数被忽略了。 useState 更新程序不会浅层合并更新,并且您的更新程序被声明为仅包含一个值。我建议还使用功能状态更新来切换布尔状态值。

handleOpenArticle(article) {
  this.setState({
    isArticleVisible: !this.state.isArticleVisible,
    article
  });

  setTimeout(() => {
    this.setState({
      timeout: !this.state.timeout
    });
  }, 325);

  setTimeout(() => {
    this.setState({
      articleTimeout: !this.state.articleTimeout
    });
  }, 350);
}

handleCloseArticle() {
  this.setState({
    articleTimeout: !this.state.articleTimeout
  });

  setTimeout(() => {
    this.setState({
      timeout: !this.state.timeout
    });
  }, 325);

  setTimeout(() => {
    this.setState({
      isArticleVisible: !this.state.isArticleVisible,
      article: ""
    });
  }, 350);
}

变成

const handleOpenArticle = (article) => {
  setIsArticleVisible(isArticleVisible => !isArticleVisible);
  setArticle(article);
  setTimeout(() => setTimeout(timeout => !timeout), 325);
  setTimeout(() => setArticleTimeout(articleTimeout => !articleTimeout), 350);
};

const handleCloseArticle = (article) => {
  setArticleTimeout(articleTimeout => !articleTimeout);
  setTimeout(() => setTimeout(timeout => !timeout), 325);
  setTimeout(() => {
    setIsArticleVisible(isArticleVisible => !isArticleVisible);
    setArticle("");
  }, 350);
};

33:6 warning React Hook useEffect has a missing dependency: 'handleClickOutside'. Either include it or remove the dependency array react-hooks/exhaustive-deps

通常您会希望包含效果的所有依赖项,以便所有值都是正确的,但这里的意图很明显是在组件安装时添加侦听器,并在卸载时删除它们。您可以为 该行添加 eslint-disable 注释。我还建议将 timeoutId/timeOutId 声明移到效果内部,因为它不会在效果外部使用。把undefined传给[=36=也是安全的,它能处理,所以去掉条件检查。

useEffect(() => {
  const timeoutId = setTimeout(() => {
    setLoading("");
  }, 100);

  document.addEventListener("mousedown", handleClickOutside);

  return () => {
    clearTimeout(timeoutId);
    document.removeEventListener("mousedown", handleClickOutside);
  };
  // Effect triggered on component mount only
  // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

58:37 warning Expected '===' and instead saw '==' eqeqeq

不确定这个逻辑从何而来,但它已被上面的 wrapperRef 错误修复所取代。

注:

以上所有建议完全基于您的self-described/reported问题以及我在您的沙箱中看到的标记。解决这些问题后可能还会出现其他潜在问题(可能是因为它们被它们掩盖了。