反应:useState 延迟问题

时间:2021-01-26 14:52:25

标签: reactjs react-hooks

我试图用 await axios 函数的结果更新状态,但状态在一个周期内不同步。这是代码...

 const Index=() => {
  const [fileSelected, setfileSelected]=useState(null)
  const [uploadId, setuploadId]=useState('')
  const [Fred, setFred]=useState('')
  const [fileName, setfileName]=useState('')
  const [fileType, setfileType]=useState('')
  const [uploadPC, setuploadPC]=useState()
  const [backendUrl, setbackendUrl]=useState('http://localhost:4000')

  useEffect(() => {
    console.log("inside useEffect: ", Fred);
  }, [Fred]);
  
  const fileHandler=async(e) =>{
    try {
      let fileSelected = document.getElementById('myfile').files[0]
      let fileName = fileSelected.name
      let fileType = fileSelected.type
      setfileSelected(fileSelected)
      setfileName(fileName)
      setfileType(fileType)
      console.log(fileSelected)
    } catch (err) {
      console.error(err, err.message) 
    }
  }

   const startUpload=async(e) =>{
    try {
      e.preventDefault()
      
      const params = {
        fileName: fileName,
        fileType: fileSelected.type
      };
      
      let resp = await axios.get(`${backendUrl}/start-upload`, { params })
      const { uploadId } = resp.data
      console.log(uploadId)// this is all OK
      setFred(uploadId)
      console.log(Fred)//"This displays the previous cycle: ",
      uploadMultipartFile()
    } catch (err) {
      console.log("startupload ",err)
    }
  }

   const uploadMultipartFile=async() =>{    
    try {
      console.log('Delayed access to the state in here',Fred)
      const fileSize = fileSelected.size
      const CHUNK_SIZE = 5000000 // 5MB
      const CHUNKS_COUNT = Math.floor(fileSize / CHUNK_SIZE) + 1
      let promisesArray = []
      let start, end, blob
      console.log(uploadId)
      for (let index = 1; index < CHUNKS_COUNT + 1; index++) {
        start = (index - 1) * CHUNK_SIZE
        end = (index) * CHUNK_SIZE
        blob = (index < CHUNKS_COUNT) ? fileSelected.slice(start, end) : fileSelected.slice(start)

        let getUploadUrlResp = await axios.get(`${backendUrl}/get-upload-url`, {
          params: {
            fileName: fileName,
            partNumber: index,
            uploadId: Fred,
          }
        })
etc

uploadMultipartFile 中没有正确的 uploadId,这会导致大问题。

我听说我应该useEffect,但目前不确定如何操作。我正在从一个类中重构并且工作正常

2 个答案:

答案 0 :(得分:1)

setFred 是一种异步方法,因此您无法在 Fred 之后立即获取 setFred() 的更新值。

setFred(uploadId)
console.log(Fred) // This will console old state value of `Fred`

您应该使用 useEffect 并添加一个 Fred 依赖项来检查更新的值。

useEffect(() => {
  console.log(Fred)
  if (Fred) // This means if Fred is not default empty state.
    uploadMultipartFile()
}, [Fred])

答案 1 :(得分:0)

看看这是否有帮助:

你能把 uploadMultipartFile() 移出你的组件吗?让 setState 调用来自 startUpload

const startUpload = async (e) => {
  try {
    // 1 - GATHER NECESSARY PARAMETERS HERE fileName uploadId etc...
    // 2 - CALL await uploadMultipartFile(...necessaryParameters)
    // 3 - SET NECESSARY STATE AFTER SUCCESSFUL UPLOAD
  }
  catch {
    // HANDLE ERRORS FROM UPLOAD CODE
  }
}

这能解决您的问题吗?