-1

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

类组件:classBasedComponent.js [本文件包含的原始代码]

我取得的进展:

函数组件:functionComponent.js [我的进度]

这是供参考的 GitHub 链接:https ://github.com/codebushi/gatsby-starter-dimension

这是我的错误:

  • 12:19 警告“setArticle”被分配了一个值,但从未使用过 no-unused-vars
  • 27:11 错误 'timeoutId' 未定义 no-undef
  • 33:6 警告 React Hook useEffect 缺少依赖项:“handleClickOutside”。要么包含它,要么移除依赖数组 react-hooks/exhaustive-deps
  • 45:30 错误 'setWrapperRef' 未定义 no-undef
  • 58:37 警告应为“===”,而是看到“==”eqeqeq
  • 66:23 错误“位置”无限制全局变量的意外使用
  • 80:28 错误 'setWrapperRef' 未定义 no-undef

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

4

1 回答 1

1

让我们专注于错误。

27:11 错误 'timeoutId' 未定义 no-undef

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

45:30 错误 'setWrapperRef' 未定义 no-undef

80:28 错误 'setWrapperRef' 未定义 no-undef

看起来是一个被调用的函数,Main用于将 ref 传回给在. 使用 react ref 来存储值。handleClickOutside

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 错误“位置”无限制全局变量的意外使用

location以前是通过 收到props的,很可能仍然是通过 收到的props

<Layout location={props.location}>

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

function IndexPage({ location }) { ...

现在警告

12:19 警告“setArticle”被分配了一个值,但从未使用过 no-unused-vars

这只是意味着它被定义并且从未使用过,但是在检查基于类的组件时,更新article值发生在handleOpenArticle和中handleCloseArticle。所以让我们在你的功能组件中做同样的事情。

这里的问题是您将额外的参数传递给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 警告 React Hook useEffect 缺少依赖项:“handleClickOutside”。要么包含它,要么移除依赖数组 react-hooks/exhaustive-deps

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

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 警告应为“===”,而是看到“==”eqeqeq

不知道这个逻辑是从哪里来的,但它被wrapperRef上面的错误修复所取代。

笔记:

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

于 2020-12-31T10:55:59.520 回答