【问题标题】:How to wait for react asynchronoes setStates [duplicate]如何等待反应同步setState [重复]
【发布时间】:2021-07-26 07:11:43
【问题描述】:

我正在尝试将文件上传到状态变量中。

function CreateCarouselPost() {
  const [file, setFile] = useState(null);
  
  const handleFileUpload = (e) => {
    setFile(e.target.files[0]); 
    console.log(file); // file is still null 
  }

  return (
    <div className='create-carousel-container'>
      <h2 className='create-carousel-header'>Add Images and Videos</h2>
      <div className='create-carousel-grid'>
        <div className='add-image-video-card grid-item'>
          <input
            className='carousel-file-upload'
            type='file'
            name='content'
            accept='image/*,video/*'
            onChange={handleFileUpload}
          />
        </div>
      </div>
    </div>
  );
}

但我知道 setState 是异步的,可能需要时间。因此,当我在 setFile 之后立即执行 console.log 文件时,文件仍然为空。当我上传另一个文件时,它具有前一个文件的内容。所以,我试图通过使用 Promises 来等待它,但我无法让它工作。

import React, { useState, useEffect } from 'react';
import AddIcon from '@material-ui/icons/Add';
import './styles/Carousel.css';

function CreateCarouselPost() {
  const [file, setFile] = useState(null);

  const uploadFile = (file) => {
    return new Promise((resolve) => {
      setFile(file);
      resolve();
    });
  };

  const handleFileUpload = (e) => {
    uploadFile(e.target.files[0]).then(() => {
      console.log('file = ', file);
    });
  };

  return (
    <div className='create-carousel-container'>
      <h2 className='create-carousel-header'>Add Images and Videos</h2>
      <div className='create-carousel-grid'>
        <div className='add-image-video-card grid-item'>
          <input
            className='carousel-file-upload'
            type='file'
            name='content'
            accept='image/*,video/*'
            onChange={handleFileUpload}
          />
        </div>
      </div>
    </div>
  );
}

export default CreateCarouselPost;

据我了解,Promise 将在执行完所有内部代码后解析,然后调用 resolve 函数。所以我尝试将它放在 Promise 中并尝试访问 resolve() 中的文件状态。但事实证明问题仍然相同(没有获得最新值)。请帮助以正确的方式做到这一点。

【问题讨论】:

  • 这个问题之前已经回答过了。在这里查看:stackoverflow.com/questions/54069253/…
  • 您究竟想等待什么?要记录正确的文件,在事件处理程序中执行 console.log(e.target.files[0]) 就足够了,不需要异步的东西。
  • @Bergi 是的,我想在那之后使用 axios 发送服务器。
  • @SankethB.K 您无需等待。只需从该回调中发送e.target.files。不要使用file 常量。

标签: reactjs asynchronous promise


【解决方案1】:

你应该使用useEffect 钩子。这将作为状态设置后的回调。

例如:

function CreateCarouselPost() {
  const [file, setFile] = useState(null);
  
  const handleFileUpload = (e) => {
    setFile(e.target.files[0]); 
  }

  useEffect(() => {
    console.log(file); // after file has been added to state
  }, [file]);

  return (
    <div className='create-carousel-container'>
      <h2 className='create-carousel-header'>Add Images and Videos</h2>
      <div className='create-carousel-grid'>
        <div className='add-image-video-card grid-item'>
          <input
            className='carousel-file-upload'
            type='file'
            name='content'
            accept='image/*,video/*'
            onChange={handleFileUpload}
          />
        </div>
      </div>
    </div>
  );
}

这是useEffect 的文档: https://reactjs.org/docs/hooks-effect.html

【讨论】:

  • 谢谢它会解决我的问题。我无法获得正确的关键字来谷歌它。
猜你喜欢
  • 2019-10-21
  • 2018-08-19
  • 1970-01-01
  • 1970-01-01
  • 2018-06-17
  • 1970-01-01
  • 2020-04-14
  • 1970-01-01
  • 2020-05-12
相关资源
最近更新 更多