Sequence of rerendering and useEffect() calls
P粉722409996
P粉722409996 2024-03-22 10:16:32
0
1
411

I have components TopPage and ImagePreview and FileUploader

  1. Display first FileUploader,

  2. FileUploader changes the fileObj state of TopPage.

  3. Then, FileUploader disappeared, ImagePreview appeared, and useEffect() was called at the same time, but there was no ImagePreviewRef at this time.

When useState is called, both component re-rendering and useEffect will be called.

The command is useEffect ->re-render?

If so, how can I solve this problem?

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 }   
}

Temporary solution,

I do like this so far, Rendering ImagePreview and FileUploader Components are toggled from the beginning via display:none.

Looks a bit awkward...but works great so far.

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粉722409996
P粉722409996

reply all(1)
P粉165522886

Render uniformly, then use CSS to conditionally display the component to preserve the reference.

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

    return (
       
       
{fileObj && } > ) }
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template