Отображение объектов массива и обновление переменной состояния. данные потеряны - PullRequest
1 голос
/ 05 августа 2020

Я хочу, чтобы массив дней обновлялся до того же времени начала и окончания и обновлял его как переменную состояния. Когда я сопоставляю массив дней с формой переменной состояния обновления. При проверке логов консоли. либо обновляется только время начала, либо время окончания, либо обновляется только 1 день в переменной состояния

const daystime={
    sunday: {
      start: "3000",
      end: "3000",
    },
    monday: {
      start: "3000",
      end: "3000",
    },
    tuesday: {
      start: "3000",
      end: "3000",
    },
    wednesday: {
      start: "3000",
      end: "3000",
    },
    thursday: {
      start: "3000",
      end: "3000",
    },
    friday: {
      start: "3000",
      end: "3000",
    },
    saturday: {
      start: "3000",
      end: "3000",
    },
  }
  const [form, setForm] = React.useState(daystime);
  const [singleStartTime, setSingleStartTime] = React.useState(new Date());
  const [singleEndTime, setSingleEndTime] = React.useState(new Date());
useEffect(() => {
    if(value==='Same Timing'){
    let starttime='3000'
    let endtime='3000'
    if (singleStartTime._d) {
      if(singleStartTime._d.getMinutes().toString().length<2)
      starttime = singleStartTime._d.getHours().toString() +'0'+singleStartTime._d.getMinutes().toString();
      else
      starttime =singleStartTime._d.getHours().toString() +singleStartTime._d.getMinutes().toString();
      
      days.map((day) => {
        pass(day.title, "start", starttime);
        return "";
      });
    }
    if (singleEndTime._d) {
      if(singleEndTime._d.getMinutes().toString().length<2)
      endtime = singleEndTime._d.getHours().toString() +'0'+singleEndTime._d.getMinutes().toString();
      else
      endtime =singleEndTime._d.getHours().toString() +singleEndTime._d.getMinutes().toString();
      days.map((day) => {
        pass(day.title, "end", endtime);
        return "";
      });
    }}
  }, [singleStartTime, singleEndTime, days]);

  const pass = (day, side, time) => {
    setForm({
      ...form,
      [`${day}`]: { ...form[`${day}`], [`${side}`]: time },
    });
  };

1 Ответ

0 голосов
/ 05 августа 2020
  • Проблема

Состояние настройки работает асинхронно.

Итак, если вы это сделаете: setCounter(counter + 1); setCounter(counter + 1); он не прибавит 2 к счетчику ( вместо этого он добавляет к нему только 1), потому что вы должны позволить переменной состояния обновиться перед применением к ней нового состояния. ( увидеть это вживую )

В вашем случае вы меняете startDate и endDate в своей переменной состояния на 7 дней (28 обновлений состояния), не позволяя переменной состояния form обновляться :

const [form, setForm] = useState({'sunday': {start: 1, end: 2},
                                    'monday': {start: 1, end: 2}})
setForm([...form, {sunday: {...form.sunday, start: 100}}]);
setForm([...form, {sunday: {...form.sunday, end: 200}}]);
// After update, the form will be: {'sunday': {start: 1, end: 200}, ...}
// !!! PROBELM !!! You shouldn't use multiple setForms right after each others !!!
  • Решение:

Вместо того, чтобы устанавливать состояние несколько раз, не позволяя применить новое состояние, вы должны сначала вычислить новое состояние, а затем применить это.

Запустить в Codesandbox

useEffect(() => {
 // clone state here
  let newForm = JSON.parse(JSON.stringify(form))
  ...
    if (singleStartTime._d) {
    ...      
      days.forEach(day => {
        newForm = {
          ...newForm,
          [day.title]: { ...newForm[day.title], start: starttime }
        };
      });
    }
   // Do the same for EndTime
   // Apply the new state
   setForm(newForm)
...
}

Запустить в Codesandbox

...