[英]Return undefined Redux store state in useEffect() function
[英]How to access state/redux store in the useEffect's cleanup function?
我有一個帶有拖放組件的表單,我可以在其中上傳圖像,之后我將這些帶有 axios 的圖片發送到我的后端並將其保存在服務器端,然后在我的客戶端以預覽模式重新渲染它。 我的問題是,如果用戶上傳了一些圖片,然后他在沒有提交表單的情況下切換到另一個頁面,那么添加的圖片會無緣無故地留在我的服務器端。 為了解決這個問題,我嘗試在清理 function 時檢測用戶是否離開頁面並且這部分工作正常。
問題是:在 useEffect clear function 內部,我嘗試訪問存儲圖像路徑的 state,但它總是給我初始的 Z9ED39E2EA931586B6A985A6942EF573E。 如果我添加了 state 作為 useEffect 的輸入,那么在每個圖像添加/狀態中修改清除 function 被觸發並導致我錯誤/不需要的行為。 因此,我決定將我的圖像鏈接移動到全局 redux 商店,但是當我嘗試訪問這家商店時,我也得到了商店的初始 state (這是一個空數組)但是里面有元素。 所以我的問題是如何訪問狀態/全局 state 並在清晰的 function 中清理我的后端圖像?
我的代碼
function Product(props) {
const globalStoreImgaes = useSelector(state => state.product.addedImages)
const [Images,setImages] = useState([])
useEffect(() => {
const initialObj = {
...key:values
}
dispatch(setProduct(initialObj)); // here I initialize my global state of my product when the page loads (the setProduct function transforms the initial object to another structure)
}, []) // eslint-disable-line react-hooks/exhaustive-deps
useEffect(() => {
return function cleanup() {
console.log('Leaving',globalStoreImgaes)
console.log('Leaving',Images) // both of them are [] arrays however I have items in it
...axios call to delete from global store
};
}, []); // eslint-disable-line react-hooks/exhaustive-deps
const updateImages = (newImages) => {
dispatch(refreshImage(newImages)) // this is where i update the global store
setImages(newImages) // and my state too
}
return (
<Prompt when={isBlocking} message="There are unsaved datas. Are you sure you want to leave?"/> // if the user clicks yes the clear function activates
...somecode)
}
export default Product
這是一個經典的閉包問題,您不能將依賴項添加到 useEffect 因為您希望 function 僅在組件卸載時運行,但由於您的 useEffect 僅在初始渲染時運行,它從閉包中使用的變量在組件時都是陳舊的卸載。
要解決這種情況,您必須將 state 存儲在 ref 中,例如
function Product(props) {
const globalStoreImgaes = useSelector(state => state.product.addedImages)
const [Images,setImages] = useState([])
const ImageRef = useRef({globalStoreImages, Images})
useEffect(() => {
ImageRef.current = {globalStoreImages, Images};
}, [globalStoreImages, Images])
useEffect(() => {
const initialObj = {
...key:values
}
dispatch(setProduct(initialObj)); // here I initialize my global state of my product when the page loads (the setProduct function transforms the initial object to another structure)
}, []) // eslint-disable-line react-hooks/exhaustive-deps
useEffect(() => {
return function cleanup() {
console.log('Leaving',ImagesRef.current.globalStoreImgaes)
console.log('Leaving',ImagesRef.current.Images)
...axios call to delete from global store
};
}, []); // eslint-disable-line react-hooks/exhaustive-deps
const updateImages = (newImages) => {
dispatch(refreshImage(newImages)) // this is where i update the global store
setImages(newImages) // and my state too
}
注意:如果您不喜歡這種方法,您可以回退到 class 組件,在這些組件中您不會遇到實施 componentWillUnmount 的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.