将 class 组件转换为函数组件时出错
Error converting class component to function component
我正在尝试将 class 组件转换为功能组件。
Class 组件:classBasedComponent.js [此文件中包含的原始代码]
我的进步:
功能组件:functionComponent.js[我的进度]
这里是GitHublink供参考:https://github.com/codebushi/gatsby-starter-dimension
这是我的错误:
- 12:19 警告 'setArticle' 已分配一个值但从未使用过
没有未使用的变量
- 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 错误 'location' no-restricted-globals
的意外使用
- 80:28 错误 'setWrapperRef' 未定义 no-undef
我仍然遇到错误。我可以在哪里即兴创作?
让我们关注错误。
27:11 error 'timeoutId' is not defined no-undef
您将此变量声明为 timeoutId
,但在引用它时在 timeoutId
和 timeOutId
之间切换。在您当前的沙箱中,它是 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
值发生在 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 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问题以及我在您的沙箱中看到的标记。解决这些问题后可能还会出现其他潜在问题(可能是因为它们被它们掩盖了。
我正在尝试将 class 组件转换为功能组件。
Class 组件:classBasedComponent.js [此文件中包含的原始代码]
我的进步:
功能组件:functionComponent.js[我的进度]
这里是GitHublink供参考:https://github.com/codebushi/gatsby-starter-dimension
这是我的错误:
- 12:19 警告 'setArticle' 已分配一个值但从未使用过 没有未使用的变量
- 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 错误 'location' no-restricted-globals 的意外使用
- 80:28 错误 'setWrapperRef' 未定义 no-undef
我仍然遇到错误。我可以在哪里即兴创作?
让我们关注错误。
27:11 error 'timeoutId' is not defined no-undef
您将此变量声明为 timeoutId
,但在引用它时在 timeoutId
和 timeOutId
之间切换。在您当前的沙箱中,它是 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
值发生在 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 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问题以及我在您的沙箱中看到的标记。解决这些问题后可能还会出现其他潜在问题(可能是因为它们被它们掩盖了。