搜索

首页  >  问答  >  正文

重新渲染和 useEffect() 调用的顺序

我有组件 TopPageImagePreviewFileUploader

  1. 首先显示 FileUploader

  2. FileUploader 更改了 TopPage 的 fileObj 状态。

  3. 然后,FileUploader消失了,ImagePreview出现了,同时调用了useEffect(),但是此时没有ImagePreviewRef

调用useState时,组件重新渲染和useEffect都会被调用。

命令是useEffect ->重新渲染?

如果是这样,我该如何解决这个问题?

const TopPage = (props) =>{
    const [fileObj, setFileObj ] = useState();
    const imagePreviewRef = useRef();
    useEffect(() =>{
        console.log("useEffect() is called with fileObj:",fileObj);
        console.log("imagePrevireRef.current is ready?",imagePreviewRef.current);
        imagePreviewRef.current.loadPic(fileObj);
    },[fileObj]);

    if (fileObj){
      return <ImagePreview ref={imagePreviewRef}></ImagePreview>
    }
    else {
      return <FileUploader SetFileObj=setFileObj></FileUploader>
    }
}

const FileUploader = (props) => {
   // props.setFileObj() is called here.
}
const ImagePreview = (props) => {
   const loadPic = () =>{// loadpicture to canvas }   
}

临时解决方案,

目前我确实喜欢这样, 渲染 ImagePreviewFileUploader 组件从一开始就通过 display:none 进行切换。

看起来有点尴尬......但目前效果很好。

const TopPage = (props) =>{
    const [fileObj, setFileObj ] = useState();
    const imagePreviewRef = useRef();
    useEffect(() =>{
        console.log("useEffect() is called with fileObj:",fileObj);
        console.log("imagePrevireRef.current is ready?",imagePreviewRef.current);
        imagePreviewRef.current.loadPic(fileObj);
    },[fileObj]);

    if (fileObj){
      return 
<React.Fragment>
<div style={{display:"block"}}>
<ImagePreview ref={imagePreviewRef}></ImagePreview>
</div>
<div style={{display:"none"}}>
<FileUploader SetFileObj=setFileObj></FileUploader>
</div>
</React.Fragment>
    }
    else {
      return 
<React.Fragment>
<div style={{display:"none"}}>
<FileUploader SetFileObj=setFileObj></FileUploader>
</div>
<div style={{display:"block"}}>
<ImagePreview ref={imagePreviewRef}></ImagePreview>
</div>
</React.Fragment>
    }
}

const FileUploader = (props) => {
   // props.setFileObj() is called here.
}
const ImagePreview = (props) => {
   const loadPic = () =>{// loadpicture to canvas }   
}

P粉722409996P粉722409996236 天前398

全部回复(1)我来回复

  • P粉165522886

    P粉1655228862024-03-23 00:36:53

    统一渲染,然后使用 CSS 有条件地显示组件以保留引用。

    const TopPage = (props) =>{
        const [fileObj, setFileObj ] = useState();
        const imagePreviewRef = useRef();
        useEffect(() =>{
           if(imagePreviewRef.current)
            imagePreviewRef.current.loadPic(fileObj);
        },[fileObj]);
    
        return (
          <> 
           
    {fileObj && } ) }

    回复
    0
  • 取消回复