0

I have something like this currently:

const Edit_History = (props) => {
  
    var thing = ''
  
    useEffect(() => {
      const id = props.match.params.id
        if (thing === '')
            axios.get(`http://localhost:3010/v0/student/${id}/${id}`)
            .then(({ data }) => {
                thing = data
                console.log(thing)
            })
    }, [])

    const submitHandler = async (e) => {
      console.log(thing)
      etc...
    }

When I first print out "thing" in useEffect, I get the value that I want. But when I try to print it on-submit with submit handler, it prints out an empty string, even though I don't modify the value of "string" outside of useEffect. I'm out of ideas on why this could be happening.

edit:

I originally tried using useState

const Edit_History = (props) => {
  
    const [thing, setThing] = useState("")
  
    useEffect(() => {
      const id = props.match.params.id
            axios.get(`http://localhost:3010/v0/student/${id}/${id}`)
            .then(({ data }) => {
                setThing(data)
                console.log(thing)
            })
    }, [])

    const submitHandler = async (e) => {
      console.log(thing)
      etc...
    }

but after setThing(data), thing is still undefined which was why I tried using var thing instead of useState.

  • Use useState instead of a plain var. – BFP May 24 '21 at 15:59
  • Use `setThing(data)` and use a hook `const [thing, setThing] = React.useState("")` instead of `var thing = ''`. `if (thing === '')` is unnecessary. See the docs for [hooks](https://reactjs.org/docs/hooks-state.html) and [useEffect](https://reactjs.org/docs/hooks-effect.html) – ggorlen May 24 '21 at 15:59
  • @ggorlen That was what I originally tried, but for some reason "thing" is undefined after setThing – cookiecutter02 May 24 '21 at 16:07
  • Can you edit the post to show that code? Thanks. – ggorlen May 24 '21 at 16:09
  • @ggorlen I have just updated the post – cookiecutter02 May 24 '21 at 16:10
  • Thanks. `setState` is async, it registers a new value _for the next render_, so yes, it's not necessarily going to be available on the next line. See the canonical thread [setState doesn't update the state immediately](https://stackoverflow.com/questions/41278385/setstate-doesnt-update-the-state-immediately) – ggorlen May 24 '21 at 16:12
  • Does this answer your question? [setState doesn't update the state immediately](https://stackoverflow.com/questions/41278385/setstate-doesnt-update-the-state-immediately) – ggorlen May 24 '21 at 16:13

2 Answers2

1

You almost got it right with your useState approach. Just remember, when you setState, the state is not updated immediately. If you want to see if your state got updated, write a useEffect to "listen" to it:

const Edit_History = (props) => {

const [thing, setThing] = useState("");

// this will trigger every time thing changes, whenever it changes
useEffect(
    () => console.log('thing', thing),
    [thing]
);

useEffect(() => {
  const id = props.match.params.id
        axios.get(`http://localhost:3010/v0/student/${id}/${id}`)
        .then(({ data }) => {
            setThing(data)
            console.log('data: ', data)    // see if your data is not undefined
        })
}, [])

const submitHandler = async (e) => {
  console.log(thing)
  etc...
}

Always remember, react state updates are async. Whenever you set state, it will continue completing the sync task it already has. Once done, all the setStates will trigger a "re-render" of the component with the new state values. This is when you'll see the updated states.

qaismakani
  • 441
  • 2
  • 7
  • thanks, this was helpful. I had a promise.all in my useEffect and saving the data into a usestate array only saved the last value from my promised data. I didnt think to use ANOTHER useeffect to watch for the promise data which I then save into my usestate array. – beeftosino Jul 20 '22 at 07:50
0

The component function is basically running over and over again on each render, and var thing is being re-initialized as '' each time you re-render. Use state to persist the value of the variable from render to render.

boc4life
  • 941
  • 5
  • 10