[英]React UseEffect not working on page refresh
I am using a useEffect to fetch information from my backend api.我正在使用 useEffect 从我的后端 api 获取信息。 I am using Redux and I dispatch action on useeffect.我正在使用 Redux 并在 useeffect 上调度操作。 At first, It works but after page reloads all information become null and i get this error TypeError: Cannot read property 'mainImage' of null.起初,它可以工作,但在页面重新加载后,所有信息都变为 null,我收到此错误 TypeError: Cannot read property 'mainImage' of null。 In redux dev tools, it doesnot even call the action and my redux store state it is null.在 redux 开发工具中,它甚至都没有调用该操作,而我的 redux 存储 state 它是 Z37A6259CC0C1DAE2B9877A66498。 What could be possible error?什么可能是错误? My other components are working fine, even after reloading page and I am using same method in other components also.我的其他组件工作正常,即使在重新加载页面后我也在其他组件中使用相同的方法。 I have even checked if my response data are loading or not.我什至检查了我的响应数据是否正在加载。 I even console.log('HI') in useeffect and it doesnot show我什至 console.log('HI') 在使用效果,它没有显示
Here is my that component这是我的那个组件
const ProductDetailScreen = ({match,history}) => {
const dispatch = useDispatch();
const {loading,product,error}= useSelector(state=> state.singleProduct)
useEffect(()=>{
dispatch(getProductDetails(match.params.id))
},[dispatch,match])
return (
<div className='my-5 p-3'>
<Button variant="outline-dark" onClick={()=> history.push('/')}>
<i className="fas fa-arrow-left"></i> Go Back
</Button>
{loading ? <Loader/> : error? <AlertMessage>{error}</AlertMessage>:
(
<>
<Row className='my-4'>
<Col md={4}>
<Image style={{width:'90%',height:'auto'}} alt='' fluid src={product.mainImage}/>
</Col>
<Col md={4}>
<ListGroup variant='flush'>
<ListGroup.Item>
<h3>{product.name}</h3>
</ListGroup.Item>
<ListGroup.Item>
<Rating value={product.ratings} text={`${product.numReviews} reviews`}/>
</ListGroup.Item>
<ListGroup.Item>
Quantity: {product.quantity}
</ListGroup.Item>
<ListGroup.Item>
Buyers: {product.sale}
</ListGroup.Item>
<ListGroup.Item>
<h5>Choose Version :</h5>
<ListGroup horizontal>
<Row>
{product.version.map(pro=>(
<Col key={pro._id} className='my-2 d-flex align-items-stretch' md={6}>
<ListGroup.Item>
<Form.Check defaultChecked type="radio" inline name="group1" aria-label="radio 1" />
<h6>Version: {pro.version}</h6>
<h6>Price: ${pro.price} </h6>
</ListGroup.Item>
</Col>
))}
</Row>
</ListGroup>
</ListGroup.Item>
</ListGroup>
</Col>
</Row>
</>
export default ProductDetailScreen
My reducer我的减速机
export const getProductFromID = (state={product:null},action)=>{
switch(action.type){
default:
return state
case GET_PRODUCT_REQUEST:
return {loading:true}
case GET_PRODUCT_SUCCESS:
return{loading:false, product:action.payload}
case GET_PRODUCT_FAIL:
return {loading:false,error:action.payload}
}
}
My store我的店铺
const rootReducer= combineReducers({
productsReducer: getProductsReducer,
topProducts: getTopProductReducer,
categories: getCategoriesReducer,
productCategories : getProductFromCategories,
singleProduct: getProductFromID
})
const initialState ={};
const middleWare = [thunk];
const store = createStore(rootReducer,initialState, composeWithDevTools(applyMiddleware(...middleWare)))
export default store
My action creator我的动作创造者
export const getProductDetails = (id) => async (dispatch) => {
try {
dispatch({
type: GET_PRODUCT_REQUEST
})
const res = await axios.get(`/api/products/${id}`)
dispatch({
type: GET_PRODUCT_SUCCESS,
payload: res.data
})
} catch (error) {
dispatch({
type: GET_PRODUCT_FAIL,
payload: error.response && error.response.data.message ? error.response.data.message : error.message
})
}
}
There is nothing wrong in my backend api, It works correctly in postman我的后端 api 没有任何问题,它在 postman 中正常工作
When you reload your page, your redux state is reset and hence during the first render, your product value is null and you are trying to access mainImage
from product which breaks the flow of the page.当您重新加载页面时,您的 redux state 将被重置,因此在第一次渲染期间,您的产品值为 null 并且您正尝试从产品访问mainImage
页面,这会中断。
To solve this, set the initial state in your reducer to have loading as true要解决此问题,请将减速器中的初始 state 设置为加载为 true
export const getProductFromID = (state={product:null, loading: true},action)=>{
switch(action.type){
default:
return state
case GET_PRODUCT_REQUEST:
return {loading:true}
case GET_PRODUCT_SUCCESS:
return{loading:false, product:action.payload}
case GET_PRODUCT_FAIL:
return {loading:false,error:action.payload}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.