How to register event with useEffect hooks?How do JavaScript closures work?How do I check if an element is hidden in jQuery?How do I remove a property from a JavaScript object?How do I redirect to another webpage?How do I include a JavaScript file in another JavaScript file?How to replace all occurrences of a string in JavaScriptHow to check whether a string contains a substring in JavaScript?How do I remove a particular element from an array in JavaScript?How to use foreach with array in JavaScript?How do I return the response from an asynchronous call?

Closed subgroups of abelian groups

Why has Russell's definition of numbers using equivalence classes been finally abandoned? ( If it has actually been abandoned).

how to create a data type and make it available in all Databases?

Example of a relative pronoun

Why do we use polarized capacitor?

How to determine if window is maximised or minimised from bash script

Finding files for which a command fails

My colleague's body is amazing

How to use Pandas to get the count of every combination inclusive

How can bays and straits be determined in a procedurally generated map?

Why is this code 6.5x slower with optimizations enabled?

Can town administrative "code" overule state laws like those forbidding trespassing?

Why don't electron-positron collisions release infinite energy?

How do we improve the relationship with a client software team that performs poorly and is becoming less collaborative?

XeLaTeX and pdfLaTeX ignore hyphenation

Simulate Bitwise Cyclic Tag

Need help identifying/translating a plaque in Tangier, Morocco

Patience, young "Padovan"

Can I make popcorn with any corn?

A function which translates a sentence to title-case

What is the meaning of "of trouble" in the following sentence?

New order #4: World

What Brexit solution does the DUP want?

How is the claim "I am in New York only if I am in America" the same as "If I am in New York, then I am in America?



How to register event with useEffect hooks?


How do JavaScript closures work?How do I check if an element is hidden in jQuery?How do I remove a property from a JavaScript object?How do I redirect to another webpage?How do I include a JavaScript file in another JavaScript file?How to replace all occurrences of a string in JavaScriptHow to check whether a string contains a substring in JavaScript?How do I remove a particular element from an array in JavaScript?How to use foreach with array in JavaScript?How do I return the response from an asynchronous call?






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








7















Following some Udemy course on how to register events with hooks, the instructor gave the below code:



 const [userText, setUserText] = useState('');

const handleUserKeyPress = event => (keyCode >= 65 && keyCode <= 90))
setUserText(`$userText$key`);

;

useEffect(() =>
window.addEventListener('keydown', handleUserKeyPress);

return () =>
window.removeEventListener('keydown', handleUserKeyPress);
;
);

return (
<div>
<h1>Feel free to type!</h1>
<blockquote>userText</blockquote>
</div>
);


Now it works great but I'm not convinced that this is the right way. The reason is, if I understand correctly, on each and every re-render, events will keep registering and deregistering every time and I simply don't think is the right way to go about it.



So I made a slight modification to the useEffect hooks to below



useEffect(() => 
window.addEventListener('keydown', handleUserKeyPress);

return () =>
window.removeEventListener('keydown', handleUserKeyPress);
;
, []);


By having an empty array as the second argument, letting the component to only run the effect once, imitating componentDidMount. And when I try out the result, it's weird that on every key I type, instead of appending, it's overwritten instead.



I was expecting setUserText($userText$key); to have new typed key append to current state and set as a new state but instead, it's forgetting the old state and rewriting with the new state.



Was it really the correct way that we should register and deregister event on every re-render?










share|improve this question






























    7















    Following some Udemy course on how to register events with hooks, the instructor gave the below code:



     const [userText, setUserText] = useState('');

    const handleUserKeyPress = event => (keyCode >= 65 && keyCode <= 90))
    setUserText(`$userText$key`);

    ;

    useEffect(() =>
    window.addEventListener('keydown', handleUserKeyPress);

    return () =>
    window.removeEventListener('keydown', handleUserKeyPress);
    ;
    );

    return (
    <div>
    <h1>Feel free to type!</h1>
    <blockquote>userText</blockquote>
    </div>
    );


    Now it works great but I'm not convinced that this is the right way. The reason is, if I understand correctly, on each and every re-render, events will keep registering and deregistering every time and I simply don't think is the right way to go about it.



    So I made a slight modification to the useEffect hooks to below



    useEffect(() => 
    window.addEventListener('keydown', handleUserKeyPress);

    return () =>
    window.removeEventListener('keydown', handleUserKeyPress);
    ;
    , []);


    By having an empty array as the second argument, letting the component to only run the effect once, imitating componentDidMount. And when I try out the result, it's weird that on every key I type, instead of appending, it's overwritten instead.



    I was expecting setUserText($userText$key); to have new typed key append to current state and set as a new state but instead, it's forgetting the old state and rewriting with the new state.



    Was it really the correct way that we should register and deregister event on every re-render?










    share|improve this question


























      7












      7








      7








      Following some Udemy course on how to register events with hooks, the instructor gave the below code:



       const [userText, setUserText] = useState('');

      const handleUserKeyPress = event => (keyCode >= 65 && keyCode <= 90))
      setUserText(`$userText$key`);

      ;

      useEffect(() =>
      window.addEventListener('keydown', handleUserKeyPress);

      return () =>
      window.removeEventListener('keydown', handleUserKeyPress);
      ;
      );

      return (
      <div>
      <h1>Feel free to type!</h1>
      <blockquote>userText</blockquote>
      </div>
      );


      Now it works great but I'm not convinced that this is the right way. The reason is, if I understand correctly, on each and every re-render, events will keep registering and deregistering every time and I simply don't think is the right way to go about it.



      So I made a slight modification to the useEffect hooks to below



      useEffect(() => 
      window.addEventListener('keydown', handleUserKeyPress);

      return () =>
      window.removeEventListener('keydown', handleUserKeyPress);
      ;
      , []);


      By having an empty array as the second argument, letting the component to only run the effect once, imitating componentDidMount. And when I try out the result, it's weird that on every key I type, instead of appending, it's overwritten instead.



      I was expecting setUserText($userText$key); to have new typed key append to current state and set as a new state but instead, it's forgetting the old state and rewriting with the new state.



      Was it really the correct way that we should register and deregister event on every re-render?










      share|improve this question
















      Following some Udemy course on how to register events with hooks, the instructor gave the below code:



       const [userText, setUserText] = useState('');

      const handleUserKeyPress = event => (keyCode >= 65 && keyCode <= 90))
      setUserText(`$userText$key`);

      ;

      useEffect(() =>
      window.addEventListener('keydown', handleUserKeyPress);

      return () =>
      window.removeEventListener('keydown', handleUserKeyPress);
      ;
      );

      return (
      <div>
      <h1>Feel free to type!</h1>
      <blockquote>userText</blockquote>
      </div>
      );


      Now it works great but I'm not convinced that this is the right way. The reason is, if I understand correctly, on each and every re-render, events will keep registering and deregistering every time and I simply don't think is the right way to go about it.



      So I made a slight modification to the useEffect hooks to below



      useEffect(() => 
      window.addEventListener('keydown', handleUserKeyPress);

      return () =>
      window.removeEventListener('keydown', handleUserKeyPress);
      ;
      , []);


      By having an empty array as the second argument, letting the component to only run the effect once, imitating componentDidMount. And when I try out the result, it's weird that on every key I type, instead of appending, it's overwritten instead.



      I was expecting setUserText($userText$key); to have new typed key append to current state and set as a new state but instead, it's forgetting the old state and rewriting with the new state.



      Was it really the correct way that we should register and deregister event on every re-render?







      javascript reactjs react-hooks






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited 2 hours ago









      bennygenel

      13.2k32751




      13.2k32751










      asked 4 hours ago









      IsaacIsaac

      3,7792830




      3,7792830






















          6 Answers
          6






          active

          oldest

          votes


















          4














          The best way to go about such scenarios is to see what you are doing in the event handler. If you are simply setting state using previous state, its best to use the callback pattern and register the event listeners only on initial mount. If you do not use the callback pattern the the listeners reference along with its lexical scope is being used by the event listener but a new function is created with updated closure on new render and hence in the handler you will not be able to the updated state



          const [userText, setUserText] = useState('');

          const handleUserKeyPress = event =>
          const key, keyCode = event;

          if (keyCode === 32 ;

          useEffect(() =>
          window.addEventListener('keydown', handleUserKeyPress);

          return () =>
          window.removeEventListener('keydown', handleUserKeyPress);
          ;
          , []);

          return (
          <div>
          <h1>Feel free to type!</h1>
          <blockquote>userText</blockquote>
          </div>
          );





          share|improve this answer























          • Your solution makes most sense to me as compared to others, thanks a lot!

            – Isaac
            1 hour ago











          • Glad to have helped (y)

            – Shubham Khatri
            47 mins ago


















          0














          You'll need a way to keep track of the previous state. useState helps you keep track of the current state only. From the docs, there is a way to access the old state, by using another hook.



          const prevRef = useRef();
          useEffect(() =>
          prevRef.current = userText;
          );


          I've updated your example to use this. And it works out.






          const useState, useEffect, useRef = React;

          const App = () =>
          const [userText, setUserText] = useState("");
          const prevRef = useRef();
          useEffect(() =>
          prevRef.current = userText;
          );

          const handleUserKeyPress = event =>
          const key, keyCode = event;

          if (keyCode === 32 ;

          useEffect(() =>
          window.addEventListener("keydown", handleUserKeyPress);

          return () =>
          window.removeEventListener("keydown", handleUserKeyPress);
          ;
          , []);

          return (
          <div>
          <h1>Feel free to type!</h1>
          <blockquote>userText</blockquote>
          </div>
          );
          ;

          ReactDOM.render(<App />, document.getElementById("root"));

          <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
          <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
          <div id="root"></div>








          share|improve this answer






























            0














            In the second approach, the useEffect is bound only once and hence the userText never gets updated. One approach would be to maintain a local variable which gets updated along with the userText object on every keypress.



             const [userText, setUserText] = useState('');
            let local_text = userText
            const handleUserKeyPress = event => (keyCode >= 65 && keyCode <= 90))
            local_text = `$userText$key`;
            setUserText(local_text);

            ;

            useEffect(() =>
            window.addEventListener('keydown', handleUserKeyPress);

            return () =>
            window.removeEventListener('keydown', handleUserKeyPress);
            ;
            , []);

            return (
            <div>
            <h1>Feel free to type!</h1>
            <blockquote>userText</blockquote>
            </div>
            );


            Personally I don't like the solution, feels anti-react and I think the first method is good enough and is designed to be used that way.






            share|improve this answer

























            • Do you mind to include some code to demonstrate how to achieve my objective in second method?

              – Isaac
              4 hours ago


















            0














            try this, it works same as your original code:



            useEffect(() => 
            function handlekeydownEvent(event)
            const key, keyCode = event;
            if (keyCode === 32

            document.addEventListener('keyup', handlekeydownEvent)
            return () =>
            document.removeEventListener('keyup', handlekeydownEvent)

            , [userText])


            because in your useEffect() method, it depends on the userText variable but you don't put it inside the second argument, else the userText will always be bound to the initial value '' with argument [].



            you don't need to do like this, just want to let you know why your second solution doesn't work.






            share|improve this answer

























            • By adding [userText] is exactly the same as without second argument, right? Reason is I only have userText in the above example, and without second argument simply means re-rerender on every props/state changes, I don't see how it answer my question. **P/S: ** I'm not the downvoter, thanks for your answer anyway

              – Isaac
              4 hours ago












            • hey @Isaac , yep, it is same as without second argument, I just want to let you know why your second solution doesn't work, because your second solution useEffect() depend on the userText variable but you didn't put inside the second arguments.

              – Spark.Bao
              3 hours ago












            • But by adding in [userText], it also means register and deregister the event on every re-render right?

              – Isaac
              3 hours ago











            • exactly! that why I say it is same with your first solution.

              – Spark.Bao
              3 hours ago






            • 1





              got what you mean, if you really want to register it only one time in this example, then you need to use useRef, just as @Maaz Syed Adeeb 's answer.

              – Spark.Bao
              3 hours ago



















            0














            you dont have access to the changed useText state. you can comapre it to the prevState. store the state in a variable e.g.: state like so:



             const [userText, setUserText] = useState('');
            let state = ''

            const handleUserKeyPress = event =>
            const key, keyCode = event;
            if (keyCode === 32 ;

            useEffect(() =>
            window.addEventListener('keydown', handleUserKeyPress);
            return () =>
            window.removeEventListener('keydown', handleUserKeyPress);
            ;
            , []);

            return (
            <div>
            <h1>Feel free to type!</h1>
            <blockquote>userText</blockquote>
            </div>
            );





            share|improve this answer






























              0














              For your use case, useEffect needs a dependency array to track changes and based on the dependency it can determine whether to re-render or not. It is always advised to pass a dependency array to useEffect. Kindly see the code below:



              I have introduced useCallback hook.



              const useCallback, useState, useEffect = React;

              function App()
              const [userText, setUserText] = useState('');

              const handleUserKeyPress = useCallback(event => (keyCode >= 65 && keyCode <= 90))
              setUserText(`$userText$key`);

              , [userText]);

              useEffect(() =>
              window.addEventListener('keydown', handleUserKeyPress);

              return () =>
              window.removeEventListener('keydown', handleUserKeyPress);
              ;
              , [handleUserKeyPress]);

              return (
              <div>
              <blockquote>userText</blockquote>
              </div>
              );



              Edit q98jov5kvq






              share|improve this answer

























              • I've tried your solution, but it's exactly the same as [userText] or without second argument. Basically we put a console.log inside useEffect, we will see that the logging is firing every re-render, which also means, addEventListender is running every re-render

                – Isaac
                3 hours ago












              • I want to believe that is an expected behaviour. I updated my answer.

                – John Kennedy
                3 hours ago











              • On your sandbox, you've put a statement console.log('>'); within useEffect hooks, and by using your updated code, it's still logging everytime, which also means the events are still registering on every re-render

                – Isaac
                3 hours ago






              • 1





                but because of return () => window.removeEventListener('keydown', handleUserKeyPress), on every re-render, the component will register and deregister

                – Isaac
                2 hours ago






              • 1





                Exactly the behaviour that I wished for, but you can observe it @ codesandbox.io/s/n5j7qy051j

                – Isaac
                2 hours ago











              Your Answer






              StackExchange.ifUsing("editor", function ()
              StackExchange.using("externalEditor", function ()
              StackExchange.using("snippets", function ()
              StackExchange.snippets.init();
              );
              );
              , "code-snippets");

              StackExchange.ready(function()
              var channelOptions =
              tags: "".split(" "),
              id: "1"
              ;
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function()
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled)
              StackExchange.using("snippets", function()
              createEditor();
              );

              else
              createEditor();

              );

              function createEditor()
              StackExchange.prepareEditor(
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader:
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              ,
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );













              draft saved

              draft discarded


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55565444%2fhow-to-register-event-with-useeffect-hooks%23new-answer', 'question_page');

              );

              Post as a guest















              Required, but never shown

























              6 Answers
              6






              active

              oldest

              votes








              6 Answers
              6






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              4














              The best way to go about such scenarios is to see what you are doing in the event handler. If you are simply setting state using previous state, its best to use the callback pattern and register the event listeners only on initial mount. If you do not use the callback pattern the the listeners reference along with its lexical scope is being used by the event listener but a new function is created with updated closure on new render and hence in the handler you will not be able to the updated state



              const [userText, setUserText] = useState('');

              const handleUserKeyPress = event =>
              const key, keyCode = event;

              if (keyCode === 32 ;

              useEffect(() =>
              window.addEventListener('keydown', handleUserKeyPress);

              return () =>
              window.removeEventListener('keydown', handleUserKeyPress);
              ;
              , []);

              return (
              <div>
              <h1>Feel free to type!</h1>
              <blockquote>userText</blockquote>
              </div>
              );





              share|improve this answer























              • Your solution makes most sense to me as compared to others, thanks a lot!

                – Isaac
                1 hour ago











              • Glad to have helped (y)

                – Shubham Khatri
                47 mins ago















              4














              The best way to go about such scenarios is to see what you are doing in the event handler. If you are simply setting state using previous state, its best to use the callback pattern and register the event listeners only on initial mount. If you do not use the callback pattern the the listeners reference along with its lexical scope is being used by the event listener but a new function is created with updated closure on new render and hence in the handler you will not be able to the updated state



              const [userText, setUserText] = useState('');

              const handleUserKeyPress = event =>
              const key, keyCode = event;

              if (keyCode === 32 ;

              useEffect(() =>
              window.addEventListener('keydown', handleUserKeyPress);

              return () =>
              window.removeEventListener('keydown', handleUserKeyPress);
              ;
              , []);

              return (
              <div>
              <h1>Feel free to type!</h1>
              <blockquote>userText</blockquote>
              </div>
              );





              share|improve this answer























              • Your solution makes most sense to me as compared to others, thanks a lot!

                – Isaac
                1 hour ago











              • Glad to have helped (y)

                – Shubham Khatri
                47 mins ago













              4












              4








              4







              The best way to go about such scenarios is to see what you are doing in the event handler. If you are simply setting state using previous state, its best to use the callback pattern and register the event listeners only on initial mount. If you do not use the callback pattern the the listeners reference along with its lexical scope is being used by the event listener but a new function is created with updated closure on new render and hence in the handler you will not be able to the updated state



              const [userText, setUserText] = useState('');

              const handleUserKeyPress = event =>
              const key, keyCode = event;

              if (keyCode === 32 ;

              useEffect(() =>
              window.addEventListener('keydown', handleUserKeyPress);

              return () =>
              window.removeEventListener('keydown', handleUserKeyPress);
              ;
              , []);

              return (
              <div>
              <h1>Feel free to type!</h1>
              <blockquote>userText</blockquote>
              </div>
              );





              share|improve this answer













              The best way to go about such scenarios is to see what you are doing in the event handler. If you are simply setting state using previous state, its best to use the callback pattern and register the event listeners only on initial mount. If you do not use the callback pattern the the listeners reference along with its lexical scope is being used by the event listener but a new function is created with updated closure on new render and hence in the handler you will not be able to the updated state



              const [userText, setUserText] = useState('');

              const handleUserKeyPress = event =>
              const key, keyCode = event;

              if (keyCode === 32 ;

              useEffect(() =>
              window.addEventListener('keydown', handleUserKeyPress);

              return () =>
              window.removeEventListener('keydown', handleUserKeyPress);
              ;
              , []);

              return (
              <div>
              <h1>Feel free to type!</h1>
              <blockquote>userText</blockquote>
              </div>
              );






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered 1 hour ago









              Shubham KhatriShubham Khatri

              95.7k15121161




              95.7k15121161












              • Your solution makes most sense to me as compared to others, thanks a lot!

                – Isaac
                1 hour ago











              • Glad to have helped (y)

                – Shubham Khatri
                47 mins ago

















              • Your solution makes most sense to me as compared to others, thanks a lot!

                – Isaac
                1 hour ago











              • Glad to have helped (y)

                – Shubham Khatri
                47 mins ago
















              Your solution makes most sense to me as compared to others, thanks a lot!

              – Isaac
              1 hour ago





              Your solution makes most sense to me as compared to others, thanks a lot!

              – Isaac
              1 hour ago













              Glad to have helped (y)

              – Shubham Khatri
              47 mins ago





              Glad to have helped (y)

              – Shubham Khatri
              47 mins ago













              0














              You'll need a way to keep track of the previous state. useState helps you keep track of the current state only. From the docs, there is a way to access the old state, by using another hook.



              const prevRef = useRef();
              useEffect(() =>
              prevRef.current = userText;
              );


              I've updated your example to use this. And it works out.






              const useState, useEffect, useRef = React;

              const App = () =>
              const [userText, setUserText] = useState("");
              const prevRef = useRef();
              useEffect(() =>
              prevRef.current = userText;
              );

              const handleUserKeyPress = event =>
              const key, keyCode = event;

              if (keyCode === 32 ;

              useEffect(() =>
              window.addEventListener("keydown", handleUserKeyPress);

              return () =>
              window.removeEventListener("keydown", handleUserKeyPress);
              ;
              , []);

              return (
              <div>
              <h1>Feel free to type!</h1>
              <blockquote>userText</blockquote>
              </div>
              );
              ;

              ReactDOM.render(<App />, document.getElementById("root"));

              <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
              <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
              <div id="root"></div>








              share|improve this answer



























                0














                You'll need a way to keep track of the previous state. useState helps you keep track of the current state only. From the docs, there is a way to access the old state, by using another hook.



                const prevRef = useRef();
                useEffect(() =>
                prevRef.current = userText;
                );


                I've updated your example to use this. And it works out.






                const useState, useEffect, useRef = React;

                const App = () =>
                const [userText, setUserText] = useState("");
                const prevRef = useRef();
                useEffect(() =>
                prevRef.current = userText;
                );

                const handleUserKeyPress = event =>
                const key, keyCode = event;

                if (keyCode === 32 ;

                useEffect(() =>
                window.addEventListener("keydown", handleUserKeyPress);

                return () =>
                window.removeEventListener("keydown", handleUserKeyPress);
                ;
                , []);

                return (
                <div>
                <h1>Feel free to type!</h1>
                <blockquote>userText</blockquote>
                </div>
                );
                ;

                ReactDOM.render(<App />, document.getElementById("root"));

                <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
                <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
                <div id="root"></div>








                share|improve this answer

























                  0












                  0








                  0







                  You'll need a way to keep track of the previous state. useState helps you keep track of the current state only. From the docs, there is a way to access the old state, by using another hook.



                  const prevRef = useRef();
                  useEffect(() =>
                  prevRef.current = userText;
                  );


                  I've updated your example to use this. And it works out.






                  const useState, useEffect, useRef = React;

                  const App = () =>
                  const [userText, setUserText] = useState("");
                  const prevRef = useRef();
                  useEffect(() =>
                  prevRef.current = userText;
                  );

                  const handleUserKeyPress = event =>
                  const key, keyCode = event;

                  if (keyCode === 32 ;

                  useEffect(() =>
                  window.addEventListener("keydown", handleUserKeyPress);

                  return () =>
                  window.removeEventListener("keydown", handleUserKeyPress);
                  ;
                  , []);

                  return (
                  <div>
                  <h1>Feel free to type!</h1>
                  <blockquote>userText</blockquote>
                  </div>
                  );
                  ;

                  ReactDOM.render(<App />, document.getElementById("root"));

                  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
                  <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
                  <div id="root"></div>








                  share|improve this answer













                  You'll need a way to keep track of the previous state. useState helps you keep track of the current state only. From the docs, there is a way to access the old state, by using another hook.



                  const prevRef = useRef();
                  useEffect(() =>
                  prevRef.current = userText;
                  );


                  I've updated your example to use this. And it works out.






                  const useState, useEffect, useRef = React;

                  const App = () =>
                  const [userText, setUserText] = useState("");
                  const prevRef = useRef();
                  useEffect(() =>
                  prevRef.current = userText;
                  );

                  const handleUserKeyPress = event =>
                  const key, keyCode = event;

                  if (keyCode === 32 ;

                  useEffect(() =>
                  window.addEventListener("keydown", handleUserKeyPress);

                  return () =>
                  window.removeEventListener("keydown", handleUserKeyPress);
                  ;
                  , []);

                  return (
                  <div>
                  <h1>Feel free to type!</h1>
                  <blockquote>userText</blockquote>
                  </div>
                  );
                  ;

                  ReactDOM.render(<App />, document.getElementById("root"));

                  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
                  <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
                  <div id="root"></div>








                  const useState, useEffect, useRef = React;

                  const App = () =>
                  const [userText, setUserText] = useState("");
                  const prevRef = useRef();
                  useEffect(() =>
                  prevRef.current = userText;
                  );

                  const handleUserKeyPress = event =>
                  const key, keyCode = event;

                  if (keyCode === 32 ;

                  useEffect(() =>
                  window.addEventListener("keydown", handleUserKeyPress);

                  return () =>
                  window.removeEventListener("keydown", handleUserKeyPress);
                  ;
                  , []);

                  return (
                  <div>
                  <h1>Feel free to type!</h1>
                  <blockquote>userText</blockquote>
                  </div>
                  );
                  ;

                  ReactDOM.render(<App />, document.getElementById("root"));

                  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
                  <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
                  <div id="root"></div>





                  const useState, useEffect, useRef = React;

                  const App = () =>
                  const [userText, setUserText] = useState("");
                  const prevRef = useRef();
                  useEffect(() =>
                  prevRef.current = userText;
                  );

                  const handleUserKeyPress = event =>
                  const key, keyCode = event;

                  if (keyCode === 32 ;

                  useEffect(() =>
                  window.addEventListener("keydown", handleUserKeyPress);

                  return () =>
                  window.removeEventListener("keydown", handleUserKeyPress);
                  ;
                  , []);

                  return (
                  <div>
                  <h1>Feel free to type!</h1>
                  <blockquote>userText</blockquote>
                  </div>
                  );
                  ;

                  ReactDOM.render(<App />, document.getElementById("root"));

                  <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
                  <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
                  <div id="root"></div>






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered 3 hours ago









                  Maaz Syed AdeebMaaz Syed Adeeb

                  2,65721426




                  2,65721426





















                      0














                      In the second approach, the useEffect is bound only once and hence the userText never gets updated. One approach would be to maintain a local variable which gets updated along with the userText object on every keypress.



                       const [userText, setUserText] = useState('');
                      let local_text = userText
                      const handleUserKeyPress = event => (keyCode >= 65 && keyCode <= 90))
                      local_text = `$userText$key`;
                      setUserText(local_text);

                      ;

                      useEffect(() =>
                      window.addEventListener('keydown', handleUserKeyPress);

                      return () =>
                      window.removeEventListener('keydown', handleUserKeyPress);
                      ;
                      , []);

                      return (
                      <div>
                      <h1>Feel free to type!</h1>
                      <blockquote>userText</blockquote>
                      </div>
                      );


                      Personally I don't like the solution, feels anti-react and I think the first method is good enough and is designed to be used that way.






                      share|improve this answer

























                      • Do you mind to include some code to demonstrate how to achieve my objective in second method?

                        – Isaac
                        4 hours ago















                      0














                      In the second approach, the useEffect is bound only once and hence the userText never gets updated. One approach would be to maintain a local variable which gets updated along with the userText object on every keypress.



                       const [userText, setUserText] = useState('');
                      let local_text = userText
                      const handleUserKeyPress = event => (keyCode >= 65 && keyCode <= 90))
                      local_text = `$userText$key`;
                      setUserText(local_text);

                      ;

                      useEffect(() =>
                      window.addEventListener('keydown', handleUserKeyPress);

                      return () =>
                      window.removeEventListener('keydown', handleUserKeyPress);
                      ;
                      , []);

                      return (
                      <div>
                      <h1>Feel free to type!</h1>
                      <blockquote>userText</blockquote>
                      </div>
                      );


                      Personally I don't like the solution, feels anti-react and I think the first method is good enough and is designed to be used that way.






                      share|improve this answer

























                      • Do you mind to include some code to demonstrate how to achieve my objective in second method?

                        – Isaac
                        4 hours ago













                      0












                      0








                      0







                      In the second approach, the useEffect is bound only once and hence the userText never gets updated. One approach would be to maintain a local variable which gets updated along with the userText object on every keypress.



                       const [userText, setUserText] = useState('');
                      let local_text = userText
                      const handleUserKeyPress = event => (keyCode >= 65 && keyCode <= 90))
                      local_text = `$userText$key`;
                      setUserText(local_text);

                      ;

                      useEffect(() =>
                      window.addEventListener('keydown', handleUserKeyPress);

                      return () =>
                      window.removeEventListener('keydown', handleUserKeyPress);
                      ;
                      , []);

                      return (
                      <div>
                      <h1>Feel free to type!</h1>
                      <blockquote>userText</blockquote>
                      </div>
                      );


                      Personally I don't like the solution, feels anti-react and I think the first method is good enough and is designed to be used that way.






                      share|improve this answer















                      In the second approach, the useEffect is bound only once and hence the userText never gets updated. One approach would be to maintain a local variable which gets updated along with the userText object on every keypress.



                       const [userText, setUserText] = useState('');
                      let local_text = userText
                      const handleUserKeyPress = event => (keyCode >= 65 && keyCode <= 90))
                      local_text = `$userText$key`;
                      setUserText(local_text);

                      ;

                      useEffect(() =>
                      window.addEventListener('keydown', handleUserKeyPress);

                      return () =>
                      window.removeEventListener('keydown', handleUserKeyPress);
                      ;
                      , []);

                      return (
                      <div>
                      <h1>Feel free to type!</h1>
                      <blockquote>userText</blockquote>
                      </div>
                      );


                      Personally I don't like the solution, feels anti-react and I think the first method is good enough and is designed to be used that way.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited 3 hours ago

























                      answered 4 hours ago









                      varun agarwalvarun agarwal

                      96629




                      96629












                      • Do you mind to include some code to demonstrate how to achieve my objective in second method?

                        – Isaac
                        4 hours ago

















                      • Do you mind to include some code to demonstrate how to achieve my objective in second method?

                        – Isaac
                        4 hours ago
















                      Do you mind to include some code to demonstrate how to achieve my objective in second method?

                      – Isaac
                      4 hours ago





                      Do you mind to include some code to demonstrate how to achieve my objective in second method?

                      – Isaac
                      4 hours ago











                      0














                      try this, it works same as your original code:



                      useEffect(() => 
                      function handlekeydownEvent(event)
                      const key, keyCode = event;
                      if (keyCode === 32

                      document.addEventListener('keyup', handlekeydownEvent)
                      return () =>
                      document.removeEventListener('keyup', handlekeydownEvent)

                      , [userText])


                      because in your useEffect() method, it depends on the userText variable but you don't put it inside the second argument, else the userText will always be bound to the initial value '' with argument [].



                      you don't need to do like this, just want to let you know why your second solution doesn't work.






                      share|improve this answer

























                      • By adding [userText] is exactly the same as without second argument, right? Reason is I only have userText in the above example, and without second argument simply means re-rerender on every props/state changes, I don't see how it answer my question. **P/S: ** I'm not the downvoter, thanks for your answer anyway

                        – Isaac
                        4 hours ago












                      • hey @Isaac , yep, it is same as without second argument, I just want to let you know why your second solution doesn't work, because your second solution useEffect() depend on the userText variable but you didn't put inside the second arguments.

                        – Spark.Bao
                        3 hours ago












                      • But by adding in [userText], it also means register and deregister the event on every re-render right?

                        – Isaac
                        3 hours ago











                      • exactly! that why I say it is same with your first solution.

                        – Spark.Bao
                        3 hours ago






                      • 1





                        got what you mean, if you really want to register it only one time in this example, then you need to use useRef, just as @Maaz Syed Adeeb 's answer.

                        – Spark.Bao
                        3 hours ago
















                      0














                      try this, it works same as your original code:



                      useEffect(() => 
                      function handlekeydownEvent(event)
                      const key, keyCode = event;
                      if (keyCode === 32

                      document.addEventListener('keyup', handlekeydownEvent)
                      return () =>
                      document.removeEventListener('keyup', handlekeydownEvent)

                      , [userText])


                      because in your useEffect() method, it depends on the userText variable but you don't put it inside the second argument, else the userText will always be bound to the initial value '' with argument [].



                      you don't need to do like this, just want to let you know why your second solution doesn't work.






                      share|improve this answer

























                      • By adding [userText] is exactly the same as without second argument, right? Reason is I only have userText in the above example, and without second argument simply means re-rerender on every props/state changes, I don't see how it answer my question. **P/S: ** I'm not the downvoter, thanks for your answer anyway

                        – Isaac
                        4 hours ago












                      • hey @Isaac , yep, it is same as without second argument, I just want to let you know why your second solution doesn't work, because your second solution useEffect() depend on the userText variable but you didn't put inside the second arguments.

                        – Spark.Bao
                        3 hours ago












                      • But by adding in [userText], it also means register and deregister the event on every re-render right?

                        – Isaac
                        3 hours ago











                      • exactly! that why I say it is same with your first solution.

                        – Spark.Bao
                        3 hours ago






                      • 1





                        got what you mean, if you really want to register it only one time in this example, then you need to use useRef, just as @Maaz Syed Adeeb 's answer.

                        – Spark.Bao
                        3 hours ago














                      0












                      0








                      0







                      try this, it works same as your original code:



                      useEffect(() => 
                      function handlekeydownEvent(event)
                      const key, keyCode = event;
                      if (keyCode === 32

                      document.addEventListener('keyup', handlekeydownEvent)
                      return () =>
                      document.removeEventListener('keyup', handlekeydownEvent)

                      , [userText])


                      because in your useEffect() method, it depends on the userText variable but you don't put it inside the second argument, else the userText will always be bound to the initial value '' with argument [].



                      you don't need to do like this, just want to let you know why your second solution doesn't work.






                      share|improve this answer















                      try this, it works same as your original code:



                      useEffect(() => 
                      function handlekeydownEvent(event)
                      const key, keyCode = event;
                      if (keyCode === 32

                      document.addEventListener('keyup', handlekeydownEvent)
                      return () =>
                      document.removeEventListener('keyup', handlekeydownEvent)

                      , [userText])


                      because in your useEffect() method, it depends on the userText variable but you don't put it inside the second argument, else the userText will always be bound to the initial value '' with argument [].



                      you don't need to do like this, just want to let you know why your second solution doesn't work.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited 3 hours ago

























                      answered 4 hours ago









                      Spark.BaoSpark.Bao

                      2,6411730




                      2,6411730












                      • By adding [userText] is exactly the same as without second argument, right? Reason is I only have userText in the above example, and without second argument simply means re-rerender on every props/state changes, I don't see how it answer my question. **P/S: ** I'm not the downvoter, thanks for your answer anyway

                        – Isaac
                        4 hours ago












                      • hey @Isaac , yep, it is same as without second argument, I just want to let you know why your second solution doesn't work, because your second solution useEffect() depend on the userText variable but you didn't put inside the second arguments.

                        – Spark.Bao
                        3 hours ago












                      • But by adding in [userText], it also means register and deregister the event on every re-render right?

                        – Isaac
                        3 hours ago











                      • exactly! that why I say it is same with your first solution.

                        – Spark.Bao
                        3 hours ago






                      • 1





                        got what you mean, if you really want to register it only one time in this example, then you need to use useRef, just as @Maaz Syed Adeeb 's answer.

                        – Spark.Bao
                        3 hours ago


















                      • By adding [userText] is exactly the same as without second argument, right? Reason is I only have userText in the above example, and without second argument simply means re-rerender on every props/state changes, I don't see how it answer my question. **P/S: ** I'm not the downvoter, thanks for your answer anyway

                        – Isaac
                        4 hours ago












                      • hey @Isaac , yep, it is same as without second argument, I just want to let you know why your second solution doesn't work, because your second solution useEffect() depend on the userText variable but you didn't put inside the second arguments.

                        – Spark.Bao
                        3 hours ago












                      • But by adding in [userText], it also means register and deregister the event on every re-render right?

                        – Isaac
                        3 hours ago











                      • exactly! that why I say it is same with your first solution.

                        – Spark.Bao
                        3 hours ago






                      • 1





                        got what you mean, if you really want to register it only one time in this example, then you need to use useRef, just as @Maaz Syed Adeeb 's answer.

                        – Spark.Bao
                        3 hours ago

















                      By adding [userText] is exactly the same as without second argument, right? Reason is I only have userText in the above example, and without second argument simply means re-rerender on every props/state changes, I don't see how it answer my question. **P/S: ** I'm not the downvoter, thanks for your answer anyway

                      – Isaac
                      4 hours ago






                      By adding [userText] is exactly the same as without second argument, right? Reason is I only have userText in the above example, and without second argument simply means re-rerender on every props/state changes, I don't see how it answer my question. **P/S: ** I'm not the downvoter, thanks for your answer anyway

                      – Isaac
                      4 hours ago














                      hey @Isaac , yep, it is same as without second argument, I just want to let you know why your second solution doesn't work, because your second solution useEffect() depend on the userText variable but you didn't put inside the second arguments.

                      – Spark.Bao
                      3 hours ago






                      hey @Isaac , yep, it is same as without second argument, I just want to let you know why your second solution doesn't work, because your second solution useEffect() depend on the userText variable but you didn't put inside the second arguments.

                      – Spark.Bao
                      3 hours ago














                      But by adding in [userText], it also means register and deregister the event on every re-render right?

                      – Isaac
                      3 hours ago





                      But by adding in [userText], it also means register and deregister the event on every re-render right?

                      – Isaac
                      3 hours ago













                      exactly! that why I say it is same with your first solution.

                      – Spark.Bao
                      3 hours ago





                      exactly! that why I say it is same with your first solution.

                      – Spark.Bao
                      3 hours ago




                      1




                      1





                      got what you mean, if you really want to register it only one time in this example, then you need to use useRef, just as @Maaz Syed Adeeb 's answer.

                      – Spark.Bao
                      3 hours ago






                      got what you mean, if you really want to register it only one time in this example, then you need to use useRef, just as @Maaz Syed Adeeb 's answer.

                      – Spark.Bao
                      3 hours ago












                      0














                      you dont have access to the changed useText state. you can comapre it to the prevState. store the state in a variable e.g.: state like so:



                       const [userText, setUserText] = useState('');
                      let state = ''

                      const handleUserKeyPress = event =>
                      const key, keyCode = event;
                      if (keyCode === 32 ;

                      useEffect(() =>
                      window.addEventListener('keydown', handleUserKeyPress);
                      return () =>
                      window.removeEventListener('keydown', handleUserKeyPress);
                      ;
                      , []);

                      return (
                      <div>
                      <h1>Feel free to type!</h1>
                      <blockquote>userText</blockquote>
                      </div>
                      );





                      share|improve this answer



























                        0














                        you dont have access to the changed useText state. you can comapre it to the prevState. store the state in a variable e.g.: state like so:



                         const [userText, setUserText] = useState('');
                        let state = ''

                        const handleUserKeyPress = event =>
                        const key, keyCode = event;
                        if (keyCode === 32 ;

                        useEffect(() =>
                        window.addEventListener('keydown', handleUserKeyPress);
                        return () =>
                        window.removeEventListener('keydown', handleUserKeyPress);
                        ;
                        , []);

                        return (
                        <div>
                        <h1>Feel free to type!</h1>
                        <blockquote>userText</blockquote>
                        </div>
                        );





                        share|improve this answer

























                          0












                          0








                          0







                          you dont have access to the changed useText state. you can comapre it to the prevState. store the state in a variable e.g.: state like so:



                           const [userText, setUserText] = useState('');
                          let state = ''

                          const handleUserKeyPress = event =>
                          const key, keyCode = event;
                          if (keyCode === 32 ;

                          useEffect(() =>
                          window.addEventListener('keydown', handleUserKeyPress);
                          return () =>
                          window.removeEventListener('keydown', handleUserKeyPress);
                          ;
                          , []);

                          return (
                          <div>
                          <h1>Feel free to type!</h1>
                          <blockquote>userText</blockquote>
                          </div>
                          );





                          share|improve this answer













                          you dont have access to the changed useText state. you can comapre it to the prevState. store the state in a variable e.g.: state like so:



                           const [userText, setUserText] = useState('');
                          let state = ''

                          const handleUserKeyPress = event =>
                          const key, keyCode = event;
                          if (keyCode === 32 ;

                          useEffect(() =>
                          window.addEventListener('keydown', handleUserKeyPress);
                          return () =>
                          window.removeEventListener('keydown', handleUserKeyPress);
                          ;
                          , []);

                          return (
                          <div>
                          <h1>Feel free to type!</h1>
                          <blockquote>userText</blockquote>
                          </div>
                          );






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered 3 hours ago









                          di3di3

                          491210




                          491210





















                              0














                              For your use case, useEffect needs a dependency array to track changes and based on the dependency it can determine whether to re-render or not. It is always advised to pass a dependency array to useEffect. Kindly see the code below:



                              I have introduced useCallback hook.



                              const useCallback, useState, useEffect = React;

                              function App()
                              const [userText, setUserText] = useState('');

                              const handleUserKeyPress = useCallback(event => (keyCode >= 65 && keyCode <= 90))
                              setUserText(`$userText$key`);

                              , [userText]);

                              useEffect(() =>
                              window.addEventListener('keydown', handleUserKeyPress);

                              return () =>
                              window.removeEventListener('keydown', handleUserKeyPress);
                              ;
                              , [handleUserKeyPress]);

                              return (
                              <div>
                              <blockquote>userText</blockquote>
                              </div>
                              );



                              Edit q98jov5kvq






                              share|improve this answer

























                              • I've tried your solution, but it's exactly the same as [userText] or without second argument. Basically we put a console.log inside useEffect, we will see that the logging is firing every re-render, which also means, addEventListender is running every re-render

                                – Isaac
                                3 hours ago












                              • I want to believe that is an expected behaviour. I updated my answer.

                                – John Kennedy
                                3 hours ago











                              • On your sandbox, you've put a statement console.log('>'); within useEffect hooks, and by using your updated code, it's still logging everytime, which also means the events are still registering on every re-render

                                – Isaac
                                3 hours ago






                              • 1





                                but because of return () => window.removeEventListener('keydown', handleUserKeyPress), on every re-render, the component will register and deregister

                                – Isaac
                                2 hours ago






                              • 1





                                Exactly the behaviour that I wished for, but you can observe it @ codesandbox.io/s/n5j7qy051j

                                – Isaac
                                2 hours ago















                              0














                              For your use case, useEffect needs a dependency array to track changes and based on the dependency it can determine whether to re-render or not. It is always advised to pass a dependency array to useEffect. Kindly see the code below:



                              I have introduced useCallback hook.



                              const useCallback, useState, useEffect = React;

                              function App()
                              const [userText, setUserText] = useState('');

                              const handleUserKeyPress = useCallback(event => (keyCode >= 65 && keyCode <= 90))
                              setUserText(`$userText$key`);

                              , [userText]);

                              useEffect(() =>
                              window.addEventListener('keydown', handleUserKeyPress);

                              return () =>
                              window.removeEventListener('keydown', handleUserKeyPress);
                              ;
                              , [handleUserKeyPress]);

                              return (
                              <div>
                              <blockquote>userText</blockquote>
                              </div>
                              );



                              Edit q98jov5kvq






                              share|improve this answer

























                              • I've tried your solution, but it's exactly the same as [userText] or without second argument. Basically we put a console.log inside useEffect, we will see that the logging is firing every re-render, which also means, addEventListender is running every re-render

                                – Isaac
                                3 hours ago












                              • I want to believe that is an expected behaviour. I updated my answer.

                                – John Kennedy
                                3 hours ago











                              • On your sandbox, you've put a statement console.log('>'); within useEffect hooks, and by using your updated code, it's still logging everytime, which also means the events are still registering on every re-render

                                – Isaac
                                3 hours ago






                              • 1





                                but because of return () => window.removeEventListener('keydown', handleUserKeyPress), on every re-render, the component will register and deregister

                                – Isaac
                                2 hours ago






                              • 1





                                Exactly the behaviour that I wished for, but you can observe it @ codesandbox.io/s/n5j7qy051j

                                – Isaac
                                2 hours ago













                              0












                              0








                              0







                              For your use case, useEffect needs a dependency array to track changes and based on the dependency it can determine whether to re-render or not. It is always advised to pass a dependency array to useEffect. Kindly see the code below:



                              I have introduced useCallback hook.



                              const useCallback, useState, useEffect = React;

                              function App()
                              const [userText, setUserText] = useState('');

                              const handleUserKeyPress = useCallback(event => (keyCode >= 65 && keyCode <= 90))
                              setUserText(`$userText$key`);

                              , [userText]);

                              useEffect(() =>
                              window.addEventListener('keydown', handleUserKeyPress);

                              return () =>
                              window.removeEventListener('keydown', handleUserKeyPress);
                              ;
                              , [handleUserKeyPress]);

                              return (
                              <div>
                              <blockquote>userText</blockquote>
                              </div>
                              );



                              Edit q98jov5kvq






                              share|improve this answer















                              For your use case, useEffect needs a dependency array to track changes and based on the dependency it can determine whether to re-render or not. It is always advised to pass a dependency array to useEffect. Kindly see the code below:



                              I have introduced useCallback hook.



                              const useCallback, useState, useEffect = React;

                              function App()
                              const [userText, setUserText] = useState('');

                              const handleUserKeyPress = useCallback(event => (keyCode >= 65 && keyCode <= 90))
                              setUserText(`$userText$key`);

                              , [userText]);

                              useEffect(() =>
                              window.addEventListener('keydown', handleUserKeyPress);

                              return () =>
                              window.removeEventListener('keydown', handleUserKeyPress);
                              ;
                              , [handleUserKeyPress]);

                              return (
                              <div>
                              <blockquote>userText</blockquote>
                              </div>
                              );



                              Edit q98jov5kvq







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited 3 hours ago

























                              answered 3 hours ago









                              John KennedyJohn Kennedy

                              3,01021227




                              3,01021227












                              • I've tried your solution, but it's exactly the same as [userText] or without second argument. Basically we put a console.log inside useEffect, we will see that the logging is firing every re-render, which also means, addEventListender is running every re-render

                                – Isaac
                                3 hours ago












                              • I want to believe that is an expected behaviour. I updated my answer.

                                – John Kennedy
                                3 hours ago











                              • On your sandbox, you've put a statement console.log('>'); within useEffect hooks, and by using your updated code, it's still logging everytime, which also means the events are still registering on every re-render

                                – Isaac
                                3 hours ago






                              • 1





                                but because of return () => window.removeEventListener('keydown', handleUserKeyPress), on every re-render, the component will register and deregister

                                – Isaac
                                2 hours ago






                              • 1





                                Exactly the behaviour that I wished for, but you can observe it @ codesandbox.io/s/n5j7qy051j

                                – Isaac
                                2 hours ago

















                              • I've tried your solution, but it's exactly the same as [userText] or without second argument. Basically we put a console.log inside useEffect, we will see that the logging is firing every re-render, which also means, addEventListender is running every re-render

                                – Isaac
                                3 hours ago












                              • I want to believe that is an expected behaviour. I updated my answer.

                                – John Kennedy
                                3 hours ago











                              • On your sandbox, you've put a statement console.log('>'); within useEffect hooks, and by using your updated code, it's still logging everytime, which also means the events are still registering on every re-render

                                – Isaac
                                3 hours ago






                              • 1





                                but because of return () => window.removeEventListener('keydown', handleUserKeyPress), on every re-render, the component will register and deregister

                                – Isaac
                                2 hours ago






                              • 1





                                Exactly the behaviour that I wished for, but you can observe it @ codesandbox.io/s/n5j7qy051j

                                – Isaac
                                2 hours ago
















                              I've tried your solution, but it's exactly the same as [userText] or without second argument. Basically we put a console.log inside useEffect, we will see that the logging is firing every re-render, which also means, addEventListender is running every re-render

                              – Isaac
                              3 hours ago






                              I've tried your solution, but it's exactly the same as [userText] or without second argument. Basically we put a console.log inside useEffect, we will see that the logging is firing every re-render, which also means, addEventListender is running every re-render

                              – Isaac
                              3 hours ago














                              I want to believe that is an expected behaviour. I updated my answer.

                              – John Kennedy
                              3 hours ago





                              I want to believe that is an expected behaviour. I updated my answer.

                              – John Kennedy
                              3 hours ago













                              On your sandbox, you've put a statement console.log('>'); within useEffect hooks, and by using your updated code, it's still logging everytime, which also means the events are still registering on every re-render

                              – Isaac
                              3 hours ago





                              On your sandbox, you've put a statement console.log('>'); within useEffect hooks, and by using your updated code, it's still logging everytime, which also means the events are still registering on every re-render

                              – Isaac
                              3 hours ago




                              1




                              1





                              but because of return () => window.removeEventListener('keydown', handleUserKeyPress), on every re-render, the component will register and deregister

                              – Isaac
                              2 hours ago





                              but because of return () => window.removeEventListener('keydown', handleUserKeyPress), on every re-render, the component will register and deregister

                              – Isaac
                              2 hours ago




                              1




                              1





                              Exactly the behaviour that I wished for, but you can observe it @ codesandbox.io/s/n5j7qy051j

                              – Isaac
                              2 hours ago





                              Exactly the behaviour that I wished for, but you can observe it @ codesandbox.io/s/n5j7qy051j

                              – Isaac
                              2 hours ago

















                              draft saved

                              draft discarded
















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid


                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.

                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55565444%2fhow-to-register-event-with-useeffect-hooks%23new-answer', 'question_page');

                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Are there any AGPL-style licences that require source code modifications to be public? Planned maintenance scheduled April 23, 2019 at 23:30 UTC (7:30pm US/Eastern) Announcing the arrival of Valued Associate #679: Cesar Manara Unicorn Meta Zoo #1: Why another podcast?Force derivative works to be publicAre there any GPL like licenses for Apple App Store?Do you violate the GPL if you provide source code that cannot be compiled?GPL - is it distribution to use libraries in an appliance loaned to customers?Distributing App for free which uses GPL'ed codeModifications of server software under GPL, with web/CLI interfaceDoes using an AGPLv3-licensed library prevent me from dual-licensing my own source code?Can I publish only select code under GPLv3 from a private project?Is there published precedent regarding the scope of covered work that uses AGPL software?If MIT licensed code links to GPL licensed code what should be the license of the resulting binary program?If I use a public API endpoint that has its source code licensed under AGPL in my app, do I need to disclose my source?

                              2013 GY136 Descoberta | Órbita | Referências Menu de navegação«List Of Centaurs and Scattered-Disk Objects»«List of Known Trans-Neptunian Objects»

                              Button changing it's text & action. Good or terrible? The 2019 Stack Overflow Developer Survey Results Are Inchanging text on user mouseoverShould certain functions be “hard to find” for powerusers to discover?Custom liking function - do I need user login?Using different checkbox style for different checkbox behaviorBest Practices: Save and Exit in Software UIInteraction with remote validated formMore efficient UI to progress the user through a complicated process?Designing a popup notice for a gameShould bulk-editing functions be hidden until a table row is selected, or is there a better solution?Is it bad practice to disable (replace) the context menu?