简体   繁体   English

为什么在 Child 中没有发生对 Parent 中 state 的 useEffect 更改?

[英]Why is the useEffect changes to state in the Parent not happening in the Child?

Below is a FileUploader Component (parent) that renders ProgressBar's (children) as a file is added.下面是一个 FileUploader 组件(父),它在添加文件时呈现 ProgressBar(子)。 I intend to pass in the FileReader onprogress so that the width of the progress bar goes from 0 to 100. To test I made a useEffect counter that goes from 0 to 100. I have confirmed that the counter state is updating by console.logging counter in the useEffect, however the progress state is not being changed in the ProgressBar component and only sends over the initial 0. How do I pass the counter state into the ProgressBar child so that it goes from 0 to 100?我打算传入 FileReader onprogress,以便进度条的宽度从 0 变为 100。为了测试,我制作了一个从 0 到 100 的 useEffect 计数器。我已确认计数器状态正在由 console.logging 计数器更新在 useEffect 中,但是 ProgressBar 组件中的进度状态并未更改,并且仅发送初始 0。如何将计数器状态传递给 ProgressBar 子项,使其从 0 变为 100?

import { useState, useCallback, useEffect } from 'react'
import { useDropzone } from 'react-dropzone'

const ProgressBar = ({ exists, file, progress }) => {
  // only the first value, 0, of progress comes through, why not through 100?
  console.log(progress)
  return (
    <div className='progress-bar-component'>
      <div className='progress-bar-filename'>
        <span>{ file.name }</span>
      </div>
      <div className='progress-bar-group'>
        <div
          className={ `progress-bar${exists.length ? ' progress-bar-exists' : ''}` }
          style={ { width: `${progress}%` } }
        >
        </div>
        <div className='progress-bar-percent'>
          <span>{ exists.length ? 'Already uploaded' : `${progress}%` }</span>
        </div>
      </div>
    </div>
  )
}

const ProgressBars = ({ progressBars }) => {
  return (
    <div className='progress-bar-container'>
      {progressBars}
    </div>
  )
}

const FileUploader = () => {
  const [filesUploaded, setFilesUploaded] = useState([])
  const [progressBars, setProgressBars] = useState([])
  //
  const [counter, setCounter] = useState(0)
  const [start, setStart] = useState(false)
  useEffect(() => {
    if (start) {
      const timer = counter < 100 &&
      setInterval(() => {
        setCounter(counter + 1)
      }, 500)
      return () => clearInterval(timer)
    }
  }, [counter, start])
  //
  const onDrop = useCallback(acceptedFiles => {
    acceptedFiles.forEach(file => {
      const reader = new FileReader()

      reader.onloadstart = () => {
        return setFilesUploaded(filesUploaded => {
          return [...filesUploaded, file]
        })
      }
      reader.onabort = () => console.log('file reading was aborted')
      reader.onerror = () => console.log('file reading has failed')
      reader.onprogress = () => {
        setStart(true)
        return setProgressBars(progressBars => {
          return [
            ...progressBars,
            <ProgressBar
              key={progressBars.length}
              file={file}
              exists={filesUploaded}
              progress={counter}
            />
          ]
        })
      }
      reader.onload = () => {
        
      }
      reader.readAsArrayBuffer(file)
    })
    
  }, [filesUploaded, setStart, counter])

  const { getRootProps, getInputProps } = useDropzone({ onDrop, multiple: true })

  return (
    <div>
      <div className='file-uploader'>
        <div
          className='file-uploader-input'
          {...getRootProps()}
        >
          <input {...getInputProps()} />
          <p>Upload Files</p>
        </div>
      </div>
      <ProgressBars progressBars={progressBars} />
    </div>
  )
}

export default FileUploader

You are calling inside a callback and the useEffect does not affect the rendering of that callback.您在回调内部调用,并且 useEffect 不会影响该回调的呈现。 Try calling outside the callback, in the return part of the parent component尝试在回调外部调用,在父组件的返回部分

Something like this:像这样的东西:

 return ( <div> <div className='file-uploader'> <div className='file-uploader-input' {...getRootProps()} > <input {...getInputProps()} /> <p>Upload Files</p> </div> </div> <ProgressBar key={progressBars.length} file={file} exists={filesUploaded} progress={counter} /> <ProgressBars progressBars={progressBars} /> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM