React/Redux reducer 在初始化期间返回 undefined
React/Redux reducer returned undefined during initialization
我正在做我的第一个 React/Redux 项目。一切顺利,然后我尝试创建一个新的减速器。我认为这是一个非常简单的方法,但是当我加载页面时出现错误 "Reducer X returned undefined during initialization." 跟踪表明这是在 combineReducers() 中发生的。我发现了几个类似的问题,但他们没有解决问题。
关于这个问题:
问题是他们在 createStore() 中使用了 initialState,而我没有这样做。
关于这个问题:
问题是我拥有的减速器中缺少默认 return 值。
我的减速器代码如下。我在开头有一个 console.log() 并且根本没有被调用。
reducers/reducer_which_sorter.js
import { SORT_CAMPERS } from '../actions/index';
export default function(state = null, action) {
console.log("action is", action);
switch(action.which) {
case 'recent':
case 'alltime':
return action.which;
break;
default:
return state;
}
return state;
}
reducers/index.js
import { combineReducers } from 'redux';
import Campers from './reducer_camper_list';
import ActiveSorter from './reducer_which_sorter';
const rootReducer = combineReducers({
campers: Campers,
activeSorter: ActiveSorter
});
export default rootReducer;
一切编译正常。 webpack 没有错误。我已经对我的文件路径进行了两次、三次和四次检查。我没有看到任何错别字。谁能看到我在这里遗漏的东西?
I have a console.log() at the beginning and it is not being called at all.
这很奇怪,因为 reducer 函数必须至少用 @@INIT
操作调用一次。
尝试测试您的 rootReducer
是否被调用。将其更改为:
const rootReducer = (state = {}, action) => {
console.log('Test if rootReducer is ever called')
return {
campers: Campers(state.campers, action),
activeSorter: ActiveSorter(state.activeSorter, action)
}
}
如果它没有被调用,那么问题出在更高的地方,而不是在减速器本身。
Redux 的要求是对操作使用 type
属性,而不是像您在示例中所做的那样 which
。由于未调用您的 console.log 检查,问题可能出在您的其他减速器中(未在您的问题中显示。)
这很重要的原因是 combineReducers
正在调用具有特殊 INIT 操作类型的减速器函数:
const initialState = reducer(undefined, { type: ActionTypes.INIT })
来源:https://github.com/reactjs/redux/blob/master/src/combineReducers.js
你的函数,因为它打开 'action.which' 而不是 'action.type',无法 return 除了未定义的任何东西。
当您的 return
语句未返回有效对象时会发生此错误,当您看到此错误时,请始终检查您的减速器返回的内容。
一个更有趣的场景,我正在创建一个基本的 redux 应用程序,并引发了同样的错误,在我的例子中,我只是返回一个对象数组并得到了同样的错误,一切都很好我撞到了我的头墙,最后发现是由于非常非常基本的javascript错误。
return
语句检查同一行中的值并且不考虑下一行。
export default function(){
return // '[' should be here not in the next line ** basic mistake****
[
{
id: 1,
name: "sachin",
centuries: "100",
country: "India"
},
{
id: 2,
name: "ganguly",
centuries: "42",
country: "India"
},
{
id:3,
name: "dravid",
centuries: "40",
country: "India"
}
]
}
由于 javascript 返回未定义,combineReducers
函数没有收到预期的对象,而是未定义。
确保您有正确的 return
语句
当组装一个 reducer 时,在你的 switch 语句中你将传递一个来自 action creators type
属性 的 action.type
。 action creator 中没有 which
属性 它将传递给 reducer。
请记住动作创建者总是将普通的 JavaScript 动作对象传递给缩减器。即使它的函数被 Redux-Thunk 等中间件接收,该中间件最终也会将 action creators 函数修改为 action 对象,以发送到所有 reducer。
此外,您的案例需要是操作类型本身的值。所以假设你的动作创建者是异步的,它从某个端点获取数据,它看起来像这样:
export const allTime = () => async dispatch => {
const response = await someEndPoint.get("/all");
dispatch({ type: 'ALL_TIME', payload: response })
};
除了你的 switch 在操作 type
属性 中传递之外,大小写必须是那个 type
属性 的值,在这个例子中 'ALL_TIME'
并且你想要 return 动作创建者的有效载荷,如果你告诉我 payload
属性 是 returning which
,那么上面看起来像这样:
export const allTime = () => async dispatch => {
const which = await someEndPoint.get("/all");
dispatch({ type: 'ALL_TIME', payload: which })
};
否则,您很可能会 returnpayload: response
。
所以代替:
export default function(state = null, action) {
console.log("action is", action);
switch(action.which) {
case 'recent':
case 'alltime':
return action.which;
break;
default:
return state;
}
return state;
}
尝试:
export default function(state = null, action) {
console.log("action is", action);
switch(action.type) {
case 'ALL_TIME':
return action.response;
default:
return state;
}
};
看看上面的重构对你做了什么,我相信如果不解决错误,它会让你更接近你的目标。如果您需要重新开始,请记住 JavaScript 的规则,函数必须始终 return
一些值,因此您可能需要返回:
export default () => {
return 123;
};
如果你实现了你的错误消息肯定会消失,你可以利用这段时间来考虑你在 SO 上的问题的答案,并从中反思解决方案。你甚至可以实现:
export default () => {
return ‘howdy’;
};
您可以return一个空数组:
export default () => {
return [];
};
您可以return一个对象:
export default () => {
return {};
};
你甚至可以像这样 return null 的值:
export default () => {
return null;
};
您的错误消息将会消失。现在问题出在你的逻辑上,相当于这样做:
export default () => {
return undefined;
}
这在减速器的世界里是不可接受的。
您看到错误提示 returned undefined during initialization。因此,当 Redux 首次启动时,它会 运行 每个减速器一次。
所以这意味着你的 reducer 第一次 运行 它 returned 的值是 undefined,你的 reducer 永远不会 return undefined,无论是在初始化还是在某个时候将来当一个动作被调度时。
所以对于 reducer,你必须总是 return 除了 undefined 之外的任何值。
我正在做我的第一个 React/Redux 项目。一切顺利,然后我尝试创建一个新的减速器。我认为这是一个非常简单的方法,但是当我加载页面时出现错误 "Reducer X returned undefined during initialization." 跟踪表明这是在 combineReducers() 中发生的。我发现了几个类似的问题,但他们没有解决问题。
关于这个问题:
问题是他们在 createStore() 中使用了 initialState,而我没有这样做。
关于这个问题:
问题是我拥有的减速器中缺少默认 return 值。
我的减速器代码如下。我在开头有一个 console.log() 并且根本没有被调用。
reducers/reducer_which_sorter.js
import { SORT_CAMPERS } from '../actions/index';
export default function(state = null, action) {
console.log("action is", action);
switch(action.which) {
case 'recent':
case 'alltime':
return action.which;
break;
default:
return state;
}
return state;
}
reducers/index.js
import { combineReducers } from 'redux';
import Campers from './reducer_camper_list';
import ActiveSorter from './reducer_which_sorter';
const rootReducer = combineReducers({
campers: Campers,
activeSorter: ActiveSorter
});
export default rootReducer;
一切编译正常。 webpack 没有错误。我已经对我的文件路径进行了两次、三次和四次检查。我没有看到任何错别字。谁能看到我在这里遗漏的东西?
I have a console.log() at the beginning and it is not being called at all.
这很奇怪,因为 reducer 函数必须至少用 @@INIT
操作调用一次。
尝试测试您的 rootReducer
是否被调用。将其更改为:
const rootReducer = (state = {}, action) => {
console.log('Test if rootReducer is ever called')
return {
campers: Campers(state.campers, action),
activeSorter: ActiveSorter(state.activeSorter, action)
}
}
如果它没有被调用,那么问题出在更高的地方,而不是在减速器本身。
Redux 的要求是对操作使用 type
属性,而不是像您在示例中所做的那样 which
。由于未调用您的 console.log 检查,问题可能出在您的其他减速器中(未在您的问题中显示。)
这很重要的原因是 combineReducers
正在调用具有特殊 INIT 操作类型的减速器函数:
const initialState = reducer(undefined, { type: ActionTypes.INIT })
来源:https://github.com/reactjs/redux/blob/master/src/combineReducers.js
你的函数,因为它打开 'action.which' 而不是 'action.type',无法 return 除了未定义的任何东西。
当您的 return
语句未返回有效对象时会发生此错误,当您看到此错误时,请始终检查您的减速器返回的内容。
一个更有趣的场景,我正在创建一个基本的 redux 应用程序,并引发了同样的错误,在我的例子中,我只是返回一个对象数组并得到了同样的错误,一切都很好我撞到了我的头墙,最后发现是由于非常非常基本的javascript错误。
return
语句检查同一行中的值并且不考虑下一行。
export default function(){
return // '[' should be here not in the next line ** basic mistake****
[
{
id: 1,
name: "sachin",
centuries: "100",
country: "India"
},
{
id: 2,
name: "ganguly",
centuries: "42",
country: "India"
},
{
id:3,
name: "dravid",
centuries: "40",
country: "India"
}
]
}
由于 javascript 返回未定义,combineReducers
函数没有收到预期的对象,而是未定义。
确保您有正确的 return
语句
当组装一个 reducer 时,在你的 switch 语句中你将传递一个来自 action creators type
属性 的 action.type
。 action creator 中没有 which
属性 它将传递给 reducer。
请记住动作创建者总是将普通的 JavaScript 动作对象传递给缩减器。即使它的函数被 Redux-Thunk 等中间件接收,该中间件最终也会将 action creators 函数修改为 action 对象,以发送到所有 reducer。
此外,您的案例需要是操作类型本身的值。所以假设你的动作创建者是异步的,它从某个端点获取数据,它看起来像这样:
export const allTime = () => async dispatch => {
const response = await someEndPoint.get("/all");
dispatch({ type: 'ALL_TIME', payload: response })
};
除了你的 switch 在操作 type
属性 中传递之外,大小写必须是那个 type
属性 的值,在这个例子中 'ALL_TIME'
并且你想要 return 动作创建者的有效载荷,如果你告诉我 payload
属性 是 returning which
,那么上面看起来像这样:
export const allTime = () => async dispatch => {
const which = await someEndPoint.get("/all");
dispatch({ type: 'ALL_TIME', payload: which })
};
否则,您很可能会 returnpayload: response
。
所以代替:
export default function(state = null, action) {
console.log("action is", action);
switch(action.which) {
case 'recent':
case 'alltime':
return action.which;
break;
default:
return state;
}
return state;
}
尝试:
export default function(state = null, action) {
console.log("action is", action);
switch(action.type) {
case 'ALL_TIME':
return action.response;
default:
return state;
}
};
看看上面的重构对你做了什么,我相信如果不解决错误,它会让你更接近你的目标。如果您需要重新开始,请记住 JavaScript 的规则,函数必须始终 return
一些值,因此您可能需要返回:
export default () => {
return 123;
};
如果你实现了你的错误消息肯定会消失,你可以利用这段时间来考虑你在 SO 上的问题的答案,并从中反思解决方案。你甚至可以实现:
export default () => {
return ‘howdy’;
};
您可以return一个空数组:
export default () => {
return [];
};
您可以return一个对象:
export default () => {
return {};
};
你甚至可以像这样 return null 的值:
export default () => {
return null;
};
您的错误消息将会消失。现在问题出在你的逻辑上,相当于这样做:
export default () => {
return undefined;
}
这在减速器的世界里是不可接受的。
您看到错误提示 returned undefined during initialization。因此,当 Redux 首次启动时,它会 运行 每个减速器一次。
所以这意味着你的 reducer 第一次 运行 它 returned 的值是 undefined,你的 reducer 永远不会 return undefined,无论是在初始化还是在某个时候将来当一个动作被调度时。
所以对于 reducer,你必须总是 return 除了 undefined 之外的任何值。