1

I am completely new to ReactJS. Please be kind, I really could not find an answer to my problem.

In useEffect I update my variable (which is an array of objects) and in my onClick function I want to update my variable again.

Since useEffect runs after I create my onClick function, my variable is still empty on onClick. I need to be able to access my updated variable in my onClick function.

How can I update my variable in useEffect first, before I create my onClick function?

const [myvariable, setMyvariable] = useState([{}]);

useEffect({
    setMyVariable([{
       id: 1
    }]);
}, []);

const onClick = () => {
    // update my variable here
    setMyVariable(prev => [...prev, {name: 'My name'} ]); // <-- Code here is probably not correct but you get the idea. 
    // prev is an empty object at this point since useEffect has not run yet
}
PouncingPoodle
  • 572
  • 1
  • 5
  • 18
  • What you're saying doesn't really make sense. `myVariable` is not an array, it's an object. Your use effect will immediately set it to `{id: 1}`. Your variable is not "still empty" in the `onClick` function because the function calls `setMyVariable` and passes `prev`, which is always the most up to date state value. What issue are you facing here? Is there an error or is your app performing in an unexpected way? Or are you just concerned that the variable will not be correct in the `onClick` function? – JMadelaine Feb 27 '20 at 10:51
  • Your onClick function gets recreated every time the component updates, and the component updates every time state changes, so your onClick function always has access to up to date state. – JMadelaine Feb 27 '20 at 10:52
  • @JMadelaine Sorry, my code did not do exactly what my case is - I made the edit now that it is an array. I found the reason why it seemed like the variable was "still empty" - when you console log the variable in the onClick the variable is empty, although if you use it or show it in a h1 tag it is the value expected that has been set in the useEffect. – PouncingPoodle Feb 27 '20 at 12:15

2 Answers2

2

useEffect with an empty dependency array is made to run after the component mounts, you can't make it run before you render. And you're defining the onClick function, not running it, so it won't change the state. Is there a reason why you don't set the initial state when you initialize it?

const [myvariable, setMyvariable] = useState({id: 1});

So here's how it goes:

const [myvariable, setMyvariable] = useState([});
const loadData = () => {
  fetch(`${process.env.REACT_APP_API_URL}`, {
    method: "Get"
  })
    .then(res => {
      return res.json();
    })
    .then(resData => {
      if (resData.errors) {
        throw new Error("error.");
      }
      setMyvariable([...resData]);
    });
};
useEffect(() => {
  loadData(); // Fetchs after mount
}, []);
// Fetchs on click
return <button onClick={loadData}>Fetch</button>;
hlkughl
  • 326
  • 2
  • 3
  • Thank you for your quick and kind response. My variable data comes from an API call so I can't set the initial state to the final value. – PouncingPoodle Feb 27 '20 at 10:57
0

Here I do some minor tweaks and write as functional component to understand the concept clearly.

import React, {useState,useEffect} from 'react';

const changeName=()=>{

    const [myvariable, setMyvariable] = useState({});

    useEffect(()=>{
        setMyvariable({id:"1"});
        },[]);

const onClick = () =>{
    setMyvariable({name:"myName"});

};

    return (
        <div>
            <h1>{myvariable.name}</h1>
            <button onClick={()=>onClick()}>click me</button>
        </div>
    )

};

export default changeName;

Initially the myvariable is set to {} using useState hook

when this component mounted useEffect hook called and change object to

{id:"1"}

Then when you click the button the setMyvariable function called and change the object to

{id:1,name:"myName"}

you can view the updates/changes in h1 tag clearly. Please let me know if you didn't understand /need to understand this concept clearly.

Thanks.