Welcome to 16892 Developer Community-Open, Learning,Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I'm trying to convert a class component to functional component.

Class component: classBasedComponent.js [Original code included in this file]

Progress made by me:

Function Component: functionComponent.js [My progress]

Here is the GitHub link for reference: https://github.com/codebushi/gatsby-starter-dimension

Here are my errors:

  • 12:19 warning 'setArticle' is assigned a value but never used no-unused-vars
  • 27:11 error 'timeoutId' is not defined no-undef
  • 33:6 warning React Hook useEffect has a missing dependency: 'handleClickOutside'. Either include it or remove the dependency array react-hooks/exhaustive-deps
  • 45:30 error 'setWrapperRef' is not defined no-undef
  • 58:37 warning Expected '===' and instead saw '==' eqeqeq
  • 66:23 error Unexpected use of 'location' no-restricted-globals
  • 80:28 error 'setWrapperRef' is not defined no-undef

I'm still getting errors with it. Where can I improvise?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
344 views
Welcome To Ask or Share your Answers For Others

1 Answer

Let's focus on the errors.

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

You declared this variable as timeoutId but switch between timeoutId and timeOutId when referring to it. In your current sandbox it is timeoutId, so all the timeOutId usages are flagged as undeclared. Settle on one or the other and be consistent.

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

and

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

This looks to be a function called by Main to pass back out a ref to something that is then referenced in handleClickOutside. Use a react ref to store the value.

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 was previously received via props, it's likely still received via props.

<Layout location={props.location}>

Or since I see no other references to props in your functional component, just destructure it in the component signature. If you need to access more prop values you can simply also destructure them here.

function IndexPage({ location }) { ...

And now the warnings

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

This just means it was defined and never used, but upon inspection of the class-based component, updating the article value occurs in handleOpenArticle and handleCloseArticle. So let's do the same in your functional component.

The issue here was that you were passing extra arguments to the setIsArticleVisible updater that get ignored. useState updaters don't shallowly merge updates and yours are declared to hold only a single value. I suggest to also use a functional state update to toggle the boolean state values.

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);
}

becomes

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

Normally you would want to include all the dependencies for the effect so all values are correct, but here it is clear the intention is to add the listeners when the component mounts, and remove them when unmounting. You can add an eslint-disable comment for just that line. I suggest also moving the timeoutId/timeOutId declaration inside the effect since it isn't used outside it. It's also safe to pass undefined to clearTimeout, it can handle it, so remove the conditional check.

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

Not sure where this logic came from, but it's replaced by the wrapperRef error fix above.

Note:

All the above suggestions are based entirely on your self-described/reported issues and what I could see flagged in your sandbox. There could be other potential issues popping up after these are addressed (possibly because they were masked by them.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to 16892 Developer Community-Open, Learning and Share
...