我有元件 TopPage
和 ImagePreview
和 FileUploader
首先顯示 FileUploader
,
FileUploader 更改了 TopPage 的 fileObj 狀態。
然後,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 } }
臨時解決方案,
目前我確實喜歡這樣,
渲染 ImagePreview
和 FileUploader
元件從一開始就透過 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 } }
統一渲染,然後使用 CSS 有條件地顯示元件以保留引用。