【发布时间】:2020-09-16 23:11:53
【问题描述】:
我已经制作了一个示例电子商务网站以供练习,并且我使用了 React、Redux 和 Router-DOM。第一次,一切都完美加载。它有两条路线ScreenShot-Link。 Home 路由将我带到出现问题的主页,而 Upload 路由将我带到上传页面。但是当我再次返回 HomeRoute 时,从 API 获取的数据 不会重新渲染 > 状态加倍我的意思是现有状态保持不变,但由于某种原因,数据被再次获取,元素被渲染 2 次ScreenShot-2-Link。
如果我从另一条路线返回它,身体元素会加倍......
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;
路由器组件和导航组件
//Parent Router Comonent
const App = () => {
return (
<Router>
<AppNavBar />
<Switch>
<Route path="/" exact>
<Body />
</Route>
<Route path="/upload">
<Upload />
</Route>
<Route path="*">
<div className="vertical-center-strict top-20">
<h1 className="text-align-center">404</h1>
<h3>Page doesn't exist</h3>
<p>Please give the correct address!</p>
</div>
</Route>
</Switch>
</Router>
);
};
export default App;
//NavLink Components..
const NavBar = ()=>{
return(
<>
<NavLink activeClassName="link" to="/" exact>
<NavItem content="Home" /> //<a> element with content as a prop
<NavLink>
<NavLink activeClassName="link" to="/upload">
<NavItem content="Upload"
</NavLink>
</>
)
}
}
我的 Redux 代码:Store 和 Reducers
//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")
})
}
请帮助我,我一直在寻找解决方案 4 小时...如果您能帮助我,那就太好了...提前致谢
【问题讨论】:
标签: reactjs redux react-redux fetch react-router-dom