我将redux与react JS一起使用时代码正常工作,但是单击当前页面链接后出现问题
Too many re-renders. React limits the number of renders to prevent an infinite loop.
我尝试解决此问题,但是我不知道为什么在执行任何动作响应后都会执行调度功能, 如果链接等于当前页面,如何停止渲染或阻止重定向
减速器
const initState = {
isFetching: false,
isSuccess: false,
}
const tableReducer = (state = initState, action) => {
switch (action.type) {
case "GET_CONTENT_PENDING": {
return {...state, isFetching: false, isSuccess: false,}
break;
}
case "GET_CONTENT_REJECTED": {
return {...state, error: action.payload, isFetching: false, isSuccess: false,}
break;
}
case "GET_RESTORANT_FULFILLED": {
return {
...state,
isFetching: true,
isSuccess: true,
moreRestaurents: action.payload.moreRestaurents,
restaurent: action.payload.details
}
break;
}
case "GET_CITIES_FULFILLED": {
return {...state, isFetching: true, isSuccess: true, cities: action.payload.cities}
break;
}
case "GET_RESTO_GROUP_BY_CITY_FULFILLED": {
return {
...state,
isFetching: true,
isSuccess: true,
restaurantsGroupedBySity: action.payload.restaurantsGroupedBySity
}
break;
}
case "GET_CITY_RESTORANTS_FULFILLED": {
return {
...state,
isFetching: true,
isSuccess: true,
cityRestaurents: action.payload.cityRestaurents,
city: action.payload.city
}
break;
}
case "GET_MOST_RESERVED_FULFILLED": {
return {
...state,
isFetching: true,
isSuccess: true,
mostReservedRestaurents: action.payload.mostReservedRestaurents
}
break;
}
case "GET_TOP_RESTORANTS_FULFILLED": {
return {...state, isFetching: true, isSuccess: true, topRestaurents: action.payload.topRestaurents}
break;
}
case "GET_ALL_RESTORANTS_FULFILLED": {
return {...state, isFetching: true, isSuccess: true, allRestaurents: action.payload.allRestaurents}
break;
}
case "GET_CONTENT_FULFILLED": {
return {
...state,
isSuccess: true,
isFetching: true,
content: action.payload.content,
page: action.payload.page
}
break;
}
}
return state;
}
export default tableReducer;
主页组件
export class Home extends Component {
render() {
var cities = this.props.homeState.cities;
var content = this.props.homeState.content;
var isSuccess = this.props.homeState.isSuccess;
var isFetching = this.props.homeState.isFetching;
var page = this.props.homeState.page == "/home";
var restaurantsGroupedBySity = this.props.homeState.restaurantsGroupedBySity;
if (isFetching && isSuccess && cities && content && restaurantsGroupedBySity && page) {
var cities = this.props.homeState.cities;
var content = this.props.homeState.content;
var isSuccess = this.props.homeState.isSuccess;
var isFetching = this.props.homeState.isFetching;
var page = this.props.homeState.page == "/home";
var restaurantsGroupedBySity = this.props.homeState.restaurantsGroupedBySity;
if (isFetching && isSuccess && cities && content && restaurantsGroupedBySity && page) {
return (
} else {
return (
<div className="loader">
<img src="/media/images/table-loader.svg" alt="" />
</div>
)
}
}
}
}
const mapStateToProps = (state) => {
return {
homeState: state
}
}
const mapDispatchToProps = (dispatch, ownProps) => {
return {
getCities: getCities(dispatch),
pageContent: pageContent(dispatch, ownProps.match.path),
getRestaurantsGroupedByCity: getRestaurantsGroupedByCity(dispatch)
};
}
export default connect(mapStateToProps, mapDispatchToProps)(Home)
动作
import axios from 'axios';
export const getCities =(dispatch)=> {
let citiesQuery = '/api/get/cities';
axios.all([
axios.get(citiesQuery)
]).then(axios.spread((cities) => {
return dispatch({ type: "GET_CITIES_FULFILLED", payload: { cities: cities.data}})
})).catch (err => {
return dispatch({ type: "GET_CONTENT_REJECTED", payload: err })
});
return dispatch({ type: "GET_CONTENT_PENDING"})
}
export const getRestaurantsGroupedByCity =(dispatch)=> {
let restaurantsQuery = '/api/get/restaurants-group-by-city';
axios.all([
axios.get(restaurantsQuery),
]).then(axios.spread((response) => {
return dispatch({ type: "GET_RESTO_GROUP_BY_CITY_FULFILLED", payload: { restaurantsGroupedBySity: response.data}})
})).catch (err => {
return dispatch({ type: "GET_CONTENT_REJECTED", payload: err })
});
return dispatch({ type: "GET_CONTENT_PENDING"})
}
答案 0 :(得分:1)
我在您的代码中看到两个问题。
第一个是Home
组件中的语法错误:
// ...
if (isFetching && isSuccess && cities && content && restaurantsGroupedBySity && page) {
// HERE IS SYNTAX ERROR, did you copy your code correctly?
return (
} else {
// ...
第二个是mapDispatchToProps,为什么没有这么做according to the documentation。我看不到您的动作创建者,但通常应该是这样的:
const mapDispatchToProps = (dispatch, ownProps) => {
return {
getCities: (/* action creator args, if any */) =>
dispatch(getCities(/* action creator args, if any */)),
pageContent: (/* action creator args, if any */) =>
dispatch(pageContent(/* action creator args, if any */)),
getRestaurantsGroupedByCity: (/* action creator args, if any */) =>
dispatch(getRestaurantsGroupedByCity(/* action creator args, if any */)),
};
}
甚至最好不要使用mapDispatchToProps,只需输入object into second argument of connect:
export default connect(
mapStateToProps,
{getCities, pageContent, getRestaurantsGroupedByCity}
)(Home)
编辑(添加动作创建者的源代码之后):
在使用异步操作创建者时,应将redux-thunk
(或redux-saga,但thunk对于初学者来说更简单)中间件添加到redux配置中。
然后,您应该以这种方式重写动作创建者(请参见redux-thunk documentaion的详细信息):
import axios from 'axios';
export const getCities = () => (
(dispatch) => {
let citiesQuery = '/api/get/cities';
axios.all([
axios.get(citiesQuery)
]).then(axios.spread((cities) => {
return dispatch({type: "GET_CITIES_FULFILLED", payload: {cities: cities.data}})
})).catch(err => {
return dispatch({type: "GET_CONTENT_REJECTED", payload: err})
});
return dispatch({type: "GET_CONTENT_PENDING"})
}
)
export const getRestaurantsGroupedByCity = () => (
(dispatch) => {
let restaurantsQuery = '/api/get/restaurants-group-by-city';
axios.all([
axios.get(restaurantsQuery),
]).then(axios.spread((response) => {
return dispatch({
type: "GET_RESTO_GROUP_BY_CITY_FULFILLED",
payload: {restaurantsGroupedBySity: response.data}
})
})).catch(err => {
return dispatch({type: "GET_CONTENT_REJECTED", payload: err})
});
return dispatch({type: "GET_CONTENT_PENDING"})
}
)
可读性改进:
尝试使用对象分解,您的代码将更易读(更短)。
首页(顶部)
此:
var cities = this.props.homeState.cities;
var content = this.props.homeState.content;
var isSuccess = this.props.homeState.isSuccess;
var isFetching = this.props.homeState.isFetching;
var page = this.props.homeState.page == "/home";
var restaurantsGroupedBySity = this.props.homeState.restaurantsGroupedBySity;
if (isFetching && isSuccess && cities && content && restaurantsGroupedBySity && page) {
var cities = this.props.homeState.cities;
var content = this.props.homeState.content;
var isSuccess = this.props.homeState.isSuccess;
var isFetching = this.props.homeState.isFetching;
var page = this.props.homeState.page == "/home";
var restaurantsGroupedBySity = this.props.homeState.restaurantsGroupedBySity;
可以这样写:
const {homeState} = this.props;
const {cities, content, isSuccess, isFetching, page, restaurantsGroupedBySity} = homeState;
const isPage = page == "/home"; // I suggest to use '===' operator here
if (isFetching && isSuccess && cities && content && restaurantsGroupedBySity && isPage) {
// you should not declare the same variables here again,
// the whole this.props is readonly in whole component and will not change
// (if so there is an error somewhere)