React useState setting initial value has no effect

11,988

Solution 1

You should ensure that props.data.status is not empty.

If props.data.status is empty, the fallback value empty string ''will ensure that status is not undefined.

const data = props.data ? props.data : {};

const statusOptions = [
  { label: "Active", value: "active" },
  { label: "Inactive", value: "inactive" },
 { label: "Complete", value: "completed" },
];

const defaultStatus = statusOptions.filter(
  option => option.value === data["status"],
)[0];

const [status, setStatusValue] = useState(defaultStatus || '');


//using effect hooks and deps to execute logic as componentWillMount
    useEffect(() => {
      // check that props.data.status is non-empty and update statusValue
      if (props.data.status !== '') {
         setStatusValue(props.data.status);
      }
    }, [props.data.status]);

Solution 2

If you are facing the same issue, I think this may help

The initialState argument is the state used during the initial render. In subsequent renders, it is disregarded.

So, if the data isn't available, we shouldn't render the component as the initialState may be empty and this empty value will remain there for subsequent renders.

I hope this may help.

Share:
11,988

Related videos on Youtube

Naresh Kumar
Author by

Naresh Kumar

Updated on May 29, 2022

Comments

  • Naresh Kumar
    Naresh Kumar almost 2 years

    Below is my functional component's relevant code to the issue,

    How can I set the initial value after some processing of data within useState() hook?

    const data = props.data ? props.data : {};
    const statusOptions = [
      { label: "Active", value: "active" },
      { label: "Inactive", value: "inactive" },
      { label: "Complete", value: "completed" },
    ];
    const defaultStatus = statusOptions.filter(
      option => option.value === data["status"],
    )[0];
    
    //This does not work
    const [status, setStatusValue] = useState(defaultStatus);
    console.log(status); //undefined
    
    //Below works
    const [status, setStatusValue] = useState({
      label: "Complete",
      value: "completed",
    });
    console.log(status); //{label:"Complete",value:"completed"}
    
    • codemax
      codemax over 4 years
      your data variable is probably empty. you need to update your status inside a useEffect hook, with props.data as a dependency
    • Vaibhav Vishal
      Vaibhav Vishal over 4 years
      your filter returns an empty array. So the value of defaultStatus is undefined as the index 0 of an empty array will be undefined. Do a console.log of defaultStatus.
    • Vaibhav Vishal
      Vaibhav Vishal over 4 years
      btw simplar way to do this: const data = props.data ? props.data : {}; is const { data = {} } = props;
    • Naresh Kumar
      Naresh Kumar over 4 years
      @VaibhavVishal filter doesn't return undefined when I do console.log(). I guess the filter function takes some to execute before which set state is already completed.
    • Vaibhav Vishal
      Vaibhav Vishal over 4 years
      No.your props change, there should be multiple console logs every time props change, check the first one. First time the filter is an empty array, then props change, filter now returns values. initialState will be set only once. Put setStatusValue in useEffect as suggested in answers.
  • Naresh Kumar
    Naresh Kumar over 4 years
    I actually need the entire object as I am using it within react-select component with material-ui customisation. I tried to achieve the same within a useEffect hook with [] as deps, but still couldn't get it to work. btw data comes perfectly alright I have that sorted out.
  • AKX
    AKX over 4 years
    The const status = line in my answer acquires the current status from the options list by key.