Search code examples
javascriptreactjssetstatereact-state

unable to setstate in react


I am trying to use function components in which eventoffset value is initially set to -1. when user clicks "ok" to save the values in backend func saveEvent is called and in that calOffsetUTC is calculating the new offset and utc values which set the state values accordingly. I am trying to call addTimeline() with new offset and utc values but it seems state values are not updated.

where am i going wrong.

Any help appreciated.

const Dialog = (props: Props) => {
  let currentdate = new Date(Date.now());
  const [eventDate, seteventDate] = React.useState(currentdate);
  const [eventOffset, seteventOffset] = React.useState(-1);
  const [eventUTC, seteventUTC] = React.useState();
  const calcOffsetUTC = (date) => {
    var selectedDate = date;

    if (eventOffset == -1) {
      var offset = selectedDate.getTimezoneOffset() * 60;
      var utc = selectedDate.valueOf();
      seteventOffset(offset);              //trying to set state of "eventoffset"
      seteventTime(utc);
    }
  }
  const saveEvent = () => {
    calcOffsetUTC(eventDate);
    props.addTimeline(eventUTC, eventOffset); //latest eventoffset value is not found here.

    }
    const buttons = [];
    buttons.push({ text: translate("ok"), icon: "ok", callback: () => saveEvent() });

    return <Dialog buttons={buttons}  ></Dialog>;
}

Solution

  • Few options to use correct updated state values

    Return the next state computed values

    const Dialog = (props: Props) => {
      let currentdate = new Date(Date.now());
      const [eventDate, seteventDate] = React.useState(currentdate);
      const [eventOffset, seteventOffset] = React.useState(-1);
      const [eventUTC, seteventUTC] = React.useState();
    
      const calcOffsetUTC = (date) => {
        var selectedDate = date;
    
        if (eventOffset === -1) {
          var offset = selectedDate.getTimezoneOffset() * 60;
          var utc = selectedDate.valueOf();
          seteventOffset(offset); 
          seteventTime(utc);
          return { offset, utc }; // return computed values
        }
        return {}; // return defined object for unhappy path
      }
    
      const saveEvent = () => {
        const { offset, utc } = calcOffsetUTC(eventDate);
        offset && utc && props.addTimeline(utc, offset); // use returned values
      }
    
      const buttons = [];
      buttons.push({ text: translate("ok"), icon: "ok", callback: () => saveEvent() });
    
      return <Dialog buttons={buttons}></Dialog>;
    }
    

    Do it all in the handler

    const Dialog = (props: Props) => {
      let currentdate = new Date(Date.now());
      const [eventDate, seteventDate] = React.useState(currentdate);
      const [eventOffset, seteventOffset] = React.useState(-1);
      const [eventUTC, seteventUTC] = React.useState();
    
      const saveEvent = () => {
        var selectedDate = eventDate;
    
        if (eventOffset === -1) {
          var offset = selectedDate.getTimezoneOffset() * 60;
          var utc = selectedDate.valueOf();
          seteventOffset(offset); 
          seteventTime(utc);
          props.addTimeline(utc, offset);
        }
      }
    
      const buttons = [];
      buttons.push({ text: translate("ok"), icon: "ok", callback: () => saveEvent() });
    
      return <Dialog buttons={buttons}></Dialog>;
    }
    

    Use effect hook

    const Dialog = (props: Props) => {
      let currentdate = new Date(Date.now());
      const [eventDate, seteventDate] = React.useState(currentdate);
      const [eventOffset, seteventOffset] = React.useState(-1);
      const [eventUTC, seteventUTC] = React.useState();
    
      useEffect(() => {
        props.addTimeline(eventUTC, eventOffset); // use latest values here
      }, [eventOffset, eventUTC]);
    
      const calcOffsetUTC = (date) => {
        var selectedDate = date;
    
        if (eventOffset === -1) {
          var offset = selectedDate.getTimezoneOffset() * 60;
          var utc = selectedDate.valueOf();
          seteventOffset(offset);
          seteventTime(utc);
        }
      }
    
      const saveEvent = () => {
        calcOffsetUTC(eventDate);
      }
    
      const buttons = [];
      buttons.push({ text: translate("ok"), icon: "ok", callback: () => saveEvent() 
    });
    
      return <Dialog buttons={buttons}  ></Dialog>;
    }
    

    NOTE: With the effect you may as well just make calcOffsetUTC the callback since as this point saveEvent is merely proxying the date.