最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

javascript - React hooks vs eventListener - Stack Overflow

matteradmin3PV0评论

So... I was trying useEffect but I found a strange behavior. I have a state in a dumb ponent. I call useEffect and inside of it I add a new eventListener. This event listener has to change the state given a condition. Problem is the state never changes... Ideas?

const ponentToRender=()=>{
    const [renderStatus, changeRenderStatus]=useState(false);
    const [transitionStatus, changeTransitionStatus]=useState(false);
    if(!renderStatus){
        useEffect(()=>{
            window.addEventListener("transitionend",(event)=>{
                if(event.propertyName==="width"){
                    changeTransitionStatus(transitionStatus?false:true);
                }
            })
        })
        changeRenderStatus(true)
    }
    return (transitionStatus)?<div> First case </div>:<div> Second case</div>
}

there's another function with some DOM manipulation onMouseOver.

This function should change the state from the event listener but it doesn't.

So... I was trying useEffect but I found a strange behavior. I have a state in a dumb ponent. I call useEffect and inside of it I add a new eventListener. This event listener has to change the state given a condition. Problem is the state never changes... Ideas?

const ponentToRender=()=>{
    const [renderStatus, changeRenderStatus]=useState(false);
    const [transitionStatus, changeTransitionStatus]=useState(false);
    if(!renderStatus){
        useEffect(()=>{
            window.addEventListener("transitionend",(event)=>{
                if(event.propertyName==="width"){
                    changeTransitionStatus(transitionStatus?false:true);
                }
            })
        })
        changeRenderStatus(true)
    }
    return (transitionStatus)?<div> First case </div>:<div> Second case</div>
}

there's another function with some DOM manipulation onMouseOver.

This function should change the state from the event listener but it doesn't.

Share edited Feb 9, 2019 at 10:38 Marco Sciortino asked Feb 8, 2019 at 22:24 Marco SciortinoMarco Sciortino 811 gold badge1 silver badge7 bronze badges 1
  • please post your releavant code – Shubham Khatri Commented Feb 9, 2019 at 6:54
Add a ment  | 

1 Answer 1

Reset to default 11
  1. you can't use hooks inside a if statement, see hooks-rules
  2. you should return a clean up function from your useEffect hooks to remove the event listener and avoid memory leaks
  3. you probably want the effect to run only once, so provide an empty array as second argument to useEffect (I don't think you need renderStatus)
  4. inside the useEffect, when calling a state setter, prefer the functional form so that you always have a fresh state value.

example

const ponentToRender = () => {
  //const [renderStatus, changeRenderStatus] = useState(false);
  const [transitionStatus, changeTransitionStatus] = useState(false);

  // No condition
  useEffect(() => {
    const handler = (event) => {
      if (event.propertyName === "width") {
        //passe a function to state setter to get fresh state value
        changeTransitionStatus(transitionStatus => transitionStatus ? false : true);
      }
    };

    window.addEventListener("transitionend", handler);

    // clean up
    return () => window.removeEventListener("transitionend", handler);
  }, []); // empty array => run only once

  return (transitionStatus) ? <div> First case </div> : <div> Second case</div>
}
Post a comment

comment list (0)

  1. No comments so far