Почему при добавлении файла в state первый вызов содержит undefined?

153
02 мая 2019, 09:40

Есть компонент по добавлению файлов, я их помещаю в стейт. Собственно, функция:

private handleAddFiles = (files: any) => {
  const filesData = files.forEach(({ name, size, type, uuid }) => ({ name, size, type, uuid }));
  files.forEach(file => {
    const uuid = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/g.exec(file.preview)[0];
    file['uuid'] = uuid;
  });
  this.setState({
    files: this.state.files.concat(files),
    filesData: this.state.files.concat(filesData)
  })
  console.log(this.state.filesData); //undefined
}

то есть, Помимо самих файлов, я также в стейт кладу и информацию о них. И если сами файлы помещаются корректно, то при добавлении информации первый вызов возвращает undefined. Я знаю, что setState асинхронный, но как мне корректно положить информацию о файле?

Answer 1
const filesData = files.forEach(({ name, size, type, uuid }) =>
    ({ name, size, type, uuid }));

forEach не возвращает массив, используйте map

// зачем вообще тут по массиву проходить?? Что бы скопировать его?
const filesData = files.map(({ name, size, type, uuid }) =>
    ({ name, size, type, uuid }));
Answer 2

setState - асинхронная функция и если вы обращаетесь к стейту сразу после нее, то не факт, что стейт успел обновиться. Чтобы гарантированно выполнить что-то после обновления стейта у функции setState есть второй параметр, в котором указывается callback

this.setState({
    files: this.state.files.concat(files),
    filesData: this.state.files.concat(filesData)
}, () => {
    console.log(this.state.filesData); //теперь отработает гарантированно
});
READ ALSO
Laravel, ajax, csrf

Laravel, ajax, csrf

Возникла проблема с отправкой токена в LaravelТокен вот здесь:

157
нужно разобраться со строкой [дубликат]

нужно разобраться со строкой [дубликат]

На данный вопрос уже ответили:

146