Reactjs 组件在单击导航链接后重新渲染&多次加载相同的数据
我制作了一个示例电子商务站点用于实践&我使用了React、Redux和Router-DOM。这是第一次,所有东西都能完美地装载。它有两条路线。主页路径将我带到出现问题的主页&上传路径将我带到上传页面。但是,当我再次返回HomeRoute时,从API获取的数据不会重新呈现,相反,状态会加倍,我的意思是,现有状态保持不变,但由于某些原因,数据会再次获取,元素会呈现2次 身体元素,如果我从另一条路线返回到它会加倍。。。 动作创造者 请帮助我我已经搜索了4个小时的解决方案…如果您能帮助我,那就太好了…提前感谢您使用useEffect挂钩时,第二个参数是依赖项。。因此,如果依赖项发生变化,它会再次调用该函数。现在,由于GetProducts是一个函数,它将永远不会被调用。相反,你应该把产品放在那里Reactjs 组件在单击导航链接后重新渲染&多次加载相同的数据,reactjs,redux,react-redux,fetch,react-router-dom,Reactjs,Redux,React Redux,Fetch,React Router Dom,我制作了一个示例电子商务站点用于实践&我使用了React、Redux和Router-DOM。这是第一次,所有东西都能完美地装载。它有两条路线。主页路径将我带到出现问题的主页&上传路径将我带到上传页面。但是,当我再次返回HomeRoute时,从API获取的数据不会重新呈现,相反,状态会加倍,我的意思是,现有状态保持不变,但由于某些原因,数据会再次获取,元素会呈现2次 身体元素,如果我从另一条路线返回到它会加倍。。。 动作创造者 请帮助我我已经搜索了4个小时的解决方案…如果您能帮助我,那就太好了…提
很难看出代码中发生了什么。但我怀疑也许这就是问题所在。否则请告诉我。对于函数,我可以使用useCallback包装它并将其传递给use effect作为第二个参数吗?与你的练习相比有什么不同吗?多谢各位much@baileyhaldwin,这使情况比以前更糟。在它被渲染两次之前,当我从其他路线返回到这条路线。现在,它总是被重新渲染…有没有其他方法来修复这个问题?谢谢你的回答…很抱歉上传了太多的代码。。。
const Body = ({getProducts, deleteProduct, productState})=>{
const {products, loading, error} = productState;
useEffect(()=>{
getProducts()
}, [getProducts])
const deleteProducts = (id)=>{
deleteProduct(id)
}
return (
<div className="display-flex width-full flex-wrap justify-content-center">
{!loading && !error && products?products.map(product=>(
product.data?product.data.map(d=>(
<BodyDiv
key={uuid.v4()}
imgSrc={d.imgSrc}
title={d.title}
details={d.details}
description={d.description}
onClick={()=>deleteProducts(d._id)}
/>
)):product.map(d=>(
<BodyDiv
key={uuid.v4()}
imgSrc={d.imgSrc}
title={d.title}
details={d.details}
description={d.description}
onClick={()=>deleteProducts(d._id)}
/>
))
))
: loading&&!error
? <div className="vertical-center-strict horizontal-center-strict">Loading.......</div>
: <div className="vertical-center-strict horizontal-center-strict">No Internet!</div>
}
</div>
)
}
const BodyDiv = (props)=>{
return(
<div className="container-div width-full card tiny-padding align-self-start">
<img title={props.title} className="img-responsive hover-filter" src={props.imgSrc}/>
<h2 className="text-align-center">{props.title}</h2>
<h5>{props.details}</h5>
<p className="text-align-justify">{props.description}</p>
<button
className="btn btn-danger"
onClick={props.onClick}
>Delete</button>
</div>
)
}
BodyDiv.propTypes = {
title: PropTypes.string.isRequired,
img: PropTypes.string,
details: PropTypes.string.isRequired,
description: PropTypes.string,
onClick: PropTypes.func
}
const mapStateToProps = (state)=>({
productState: state.productState
})
const conn = connect(mapStateToProps, {getProducts, deleteProduct})(Body)
export default conn;
//Store
import {createStore, applyMiddleware} from "redux"
import rootReducer from "./reducers/index"
import thunk from "redux-thunk"
const middleWare = [thunk]
const store = createStore(rootReducer, applyMiddleware(...middleWare))
export default store
//RootReducer
import {
FETCHED_PRODUCTS,
FETCHING_PRODUCTS,
ERROR_GET_PRODUCTS,
DELETED_PRODUCT,
ERROR_DELETING_PRODUCT
} from "../actions/productActions";
const initialState = {
products: [],
loading: true,
error: false,
};
const productReducer = (state = initialState, action) => {
switch (action.type) {
case FETCHING_PRODUCTS:
return {
...state,
loading: true,
};
case FETCHED_PRODUCTS:
return {
...state,
products: state.products.concat(action.payload),
loading: false,
error: false,
};
case ERROR_GET_PRODUCTS:
return {
...state,
loading: false,
};
case DELETED_PRODUCT:
return {
...state,
products: state.products.map((product) =>
product.data.filter((d) => d._id !== action.payload)
),
error: false,
};
case ERROR_DELETING_PRODUCT:
return {
...state,
error: true,
};
default:
return state;
}
};
export default productReducer;
export const getProducts = (payload)=>(dispatch)=>{
return(
fetch("/api/products")
.then(res=>{
dispatch({
type:FETCHING_PRODUCTS
})
if(!res.ok){
dispatch({
type: ERROR_GET_PRODUCTS
})
}
return res.json();
})
.then(json=>{
if(json)dispatch({
type: FETCHED_PRODUCTS,
payload: json
})
})
.catch(err=>{
console.log("Error!! failed to fetch data: "+ err)
})
)
}
export const deleteProduct = (payload)=>dispatch=>{
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
var requestOptions = {
method: 'DELETE',
headers: myHeaders,
body: JSON.stringify({"_id": payload}),
redirect: 'follow'
};
fetch("/api/product-delete", requestOptions).then(res=>{
dispatch({
type: DELETED_PRODUCT,
payload
})
if(res.status === 501 || res.status === 403){
dispatch({
type: ERROR_DELETING_PRODUCT,
})
}
})
.catch(err=>{
console.log("Failed to Delete")
})
}
useEffect(()=>{
getProducts()
}, [products])
//will refetch data everytime product state is updated.