首页 > 解决方案 > React:useState 延迟问题

问题描述

我正在尝试使用 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

正确的 uploadId 在 uploadMultipartFile 中不可用,这会导致大问题。

我听说我应该useEffect,但目前不知道该怎么做。我正在从一个类中重构并且效果很好

标签: reactjsreact-hooks

解决方案


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

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

您应该使用useEffectwith 添加Fred依赖项来检查更新的值。

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

推荐阅读