Reihenfolge des erneuten Renderns und der useEffect()-Aufrufe
P粉722409996
P粉722409996 2024-03-22 10:16:32
0
1
415

Ich habe Komponenten TopPageImagePreviewFileUploader

  1. Zuerst anzeigen FileUploader,

  2. FileUploader ändert den fileObj-Status von TopPage.

  3. Dann verschwindet FileUploader, ImagePreview erscheint und gleichzeitig wird useEffect() aufgerufen, aber zu diesem Zeitpunkt gibt es kein ImagePreviewRef.

Wenn useState aufgerufen wird, werden sowohl das erneute Rendern der Komponente als auch useEffect aufgerufen.

Der Befehl lautet useEffect -> erneut rendern?

Wenn ja, wie kann ich dieses Problem lösen?

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

Übergangslösung,

Mir gefällt das bisher, Rendern von ImagePreview und ImagePreviewFileUploader Komponenten werden von Anfang an über display:none umgeschaltet.

Sieht etwas umständlich aus...funktioniert aber bisher großartig.

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

Antworte allen(1)
P粉165522886

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

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

    return (
       
       
{fileObj && } > ) }
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage