9
import React, { useState } from "react";
import Child from "./Child";
import "./styles.css";

export default function App() {
  let [state, setState] = useState({
    value: ""
  });

  let handleChange = input => {
    setState(prevValue => {
      return { value: input };
    });
    console.log(state.value);
  };
  return (
    <div className="App">
      <h1>{state.value}</h1>

      <Child handleChange={handleChange} value={state.value} />
    </div>
  );
}
import React from "react";

function Child(props) {
  return (
    <input
      type="text"
      placeholder="type..."
      onChange={e => {
        let newValue = e.target.value;
        props.handleChange(newValue);
      }}
      value={props.value}
    />
  );
}

export default Child;

Here I am passing the data from the input field to the parent component. However, while displaying it on the page with the h1 tag, I am able to see the latest state. But while using console.log() the output is the previous state. How do I solve this in the functional React component?

Drew Reese
  • 165,259
  • 14
  • 153
  • 181
harsha ray
  • 173
  • 1
  • 2
  • 10
  • console.log(), will always give you the previousState , since state change is async process. You can use useEffect() react hook to check the current state. – Harmandeep Singh Kalsi May 22 '20 at 08:58
  • Non-functional React uses `componentDidUpdate`; with functional React you have to use the `useEffect` hook with a dependency array containing the state variable. However, what exactly are you trying to achieve? You are composing the latest value right before the console.log() command, so you have full access to it right then and there. What's the goal here? –  May 22 '20 at 08:58
  • Check this for your reference : https://stackoverflow.com/questions/31702861/when-value-is-assigned-to-components-state-why-console-log-prints-the-previous – Harmandeep Singh Kalsi May 22 '20 at 08:59
  • @ChrisG I am just trying to have the same output at both places, in the console log and while displaying it on the page with h1 – harsha ray May 22 '20 at 09:00
  • But *why*? A console.log() has no function for the user. Anyway, just use `newState = { value: input };`, then use `newState` to update the state and log it. –  May 22 '20 at 09:06
  • @ChrisG The main idea behind this is that I have an API and want to pass the value of the input field to the API as a search query. But as I am not getting the complete value here, and the API call is failing. – harsha ray May 22 '20 at 09:08
  • Ok, but you do understand that you have access to the current value in the form of the `input` parameter the function receives, right? The state update is asynchronous so logging the state will show the previous value, but you can use the actual value at any time:`console.log(input);` –  May 22 '20 at 09:12
  • Yes I do, thanks for the explanation – harsha ray May 22 '20 at 09:18

3 Answers3

5

React state updates are asynchronous, i.e. queued up for the next render, so the log is displaying the state value from the current render cycle. You can use an effect to log the value when it updates. This way you log the same state.value as is being rendered, in the same render cycle.

export default function App() {
  const [state, setState] = useState({
    value: ""
  });

  useEffect(() => {
    console.log(state.value);
  }, [state.value]);

  let handleChange = input => {
    setState(prevValue => {
      return { value: input };
    });
  };

  return (
    <div className="App">
      <h1>{state.value}</h1>

      <Child handleChange={handleChange} value={state.value} />
    </div>
  );
}
Drew Reese
  • 165,259
  • 14
  • 153
  • 181
1

Two solution for you: - use input value in the handleChange function

let handleChange = input => {
   setState(prevValue => {
     return { value: input };
   });
   console.log(state.value);
 };
  • use a useEffect on the state

    useEffect(()=>{ console.log(state.value) },[state])

benjamin Rampon
  • 1,316
  • 11
  • 18
0
Maybe it is helpful for others I found this way...

I want all updated projects in my state as soon as I added them so that I use use effect hook like this.

useEffect(() => {
    [temp_variable] = projects //projects get from useSelector
    let newFormValues = {...data}; //data from useState
    newFormValues.Projects = pro; //update my data object
    setData(newFormValues); //set data using useState
},[projects])