createStore ()에 initialState를 제공 했음에도 불구하고 "초기화 중에 정의되지 않은 리듀서 […] 반환 됨"이 발생하는 이유는 무엇입니까?
내 redux createStore 메서드에 InitialState를 설정했으며 InitialState를 두 번째 인수로 대응했습니다.
브라우저에 오류가 있습니다.
<code>Uncaught Error: Reducer "postsBySubreddit" returned undefined during initialization. If the state passed to the reducer is undefined, you must explicitly return the initial state. The initial state may not be undefined.</code>
코드는 다음과 같습니다.
import { createStore, applyMiddleware } from 'redux'
import thunkMiddleware from 'redux-thunk'
import createLogger from 'redux-logger'
import rootReducer from '../reducers/reducers'
import Immutable from 'immutable'
const loggerMiddleware = createLogger()
//const initialState=0
function configureStore() {
return createStore(
rootReducer,
{postsBySubreddit:{},selectedSubreddit:'reactjs'},
applyMiddleware(
thunkMiddleware,
loggerMiddleware
)
)
}
export default configureStore
그리고 다음 configeStore
에서 메서드를 호출 했습니다 Root.js
.
import React, { Component } from 'react'
import { Provider } from 'react-redux'
import configureStore from '../store/configureStore'
import AsyncApp from './AsyncApp'
import Immutable from 'immutable'
const store = configureStore()
console.log(store.getState())
export default class Root extends Component {
render() {
return (
<Provider store={store}>
<AsyncApp />
</Provider>
)
}
}
하지만 이것은 initateState
뭔가 잘못되었다고 생각합니다 .
import { combineReducers } from 'redux'
import {reducerCreator} from '../utils/creator'
import Immutable from'immutable'
import {SELECT_SUBREDDIT, INVALIDATE_SUBREDDIT ,REQUEST_POSTS, RECEIVE_POSTS} from '../actions/action'
let initialState=Immutable.fromJS({isFetching: false, didInvalidate: false,items:[]})
function selectedSubreddit(state, action) {
switch (action.type) {
case SELECT_SUBREDDIT:
return action.subreddit
default:
return state
}
}
function postsBySubreddit(state, action) {
switch (action.type) {
case INVALIDATE_SUBREDDIT:
case RECEIVE_POSTS:
case REQUEST_POSTS:
return Object.assign({}, state, {
[action.subreddit]: posts(state[action.subreddit], action)
})
default:
return state
}
}
function posts(state=initialState,action) {
switch (action.type) {
case INVALIDATE_SUBREDDIT:
return state.merge({
didInvalidate: true
})
case REQUEST_POSTS:
return state.merge({
isFetching: true,
didInvalidate: false
})
case RECEIVE_POSTS:
return state.merge({
isFetching: false,
didInvalidate: false,
items: action.posts,
lastUpdated: action.receivedAt
})
default:
return state
}
}
const rootReducer = combineReducers({
postsBySubreddit,
selectedSubreddit
})
export default rootReducer
그러나 initialState
모든 하위 감속기를 설정하면 정상적으로 단어를 할 수 있습니다. 뭔가 잘못?
의 initialState
주장 createStore()
은 종종 사람들을 걸려 넘어지게합니다. 애플리케이션 상태를 수동으로 "초기화"하는 방법은 아닙니다. 유일하게 유용한 응용 프로그램은 다음과 같습니다.
- JSON 상태 페이로드에서 서버 렌더링 앱을 부팅합니다.
- 로컬 저장소에 저장된 상태에서 앱을 "재개"합니다.
initialState
수동으로 작성 하지 않으며 대부분의 앱에서 사용하지 않는다는 것을 의미합니다. 대신 리듀서는 항상 자체 초기 상태를 지정 initialState
해야하며 기존 직렬화 된 버전이있을 때 해당 상태를 미리 채우는 방법 일뿐입니다.
따라서이 대답 은 맞습니다. 감속기에서 초기 상태를 정의 해야 합니다. 제공하는 것으로 createStore()
는 충분하지 않으며 코드에서 초기 상태를 정의하는 방법이 아닙니다.
동일한 오류가 발생했지만 기본 케이스를 포함하지 않았습니다.
function generate(state={} ,action) {
switch (action.type) {
case randomNumber:
return {
...state,
random: action.payload
}
default: // need this for default case
return state
}
}
감속기가 처음 호출되면 상태가 정의되지 않습니다. 그런 다음 초기 상태를 반환해야합니다 (오류 메시지가 알려주는 것입니다). 초기 상태 값을 정의하는 일반적인 방법은 상태 매개 변수의 기본값을 설정하는 것입니다.
function postsBySubreddit(state = {}, action) {}
You have an initial state in the posts
function but it is not called during initialization.
Also, make sure that you are returning the default state last in your reducer. Sometimes you can forget to make sure this is the default for your switch statement (when refactoring and moving around code).
...
default:
return state
I just hit this same snag because I accidentally redefined state
inside my reducer:
const initialState = {
previous: true,
later: true
}
const useTypeReducer = (state = initialState, action) => {
switch (action.type) {
case 'TOGGLE_USE_TYPES':
let state = Object.assign({}, state); // DON'T REDEFINE STATE LIKE THIS!
state[action.use] = !state[action.use];
return state;
default:
return state;
}
}
export default useTypeReducer;
To fix the problem I needed to refrain from redefining state:
const initialState = {
previous: true,
later: true
}
const useTypeReducer = (state = initialState, action) => {
switch (action.type) {
case 'TOGGLE_USE_TYPES':
let _state = Object.assign({}, state); // BETTER
_state[action.use] = !state[action.use];
return _state;
default:
return state;
}
}
export default useTypeReducer;
tl;dr
Make sure that:
- You actually pass data to your reducer via the action/action creator!
- The reducer doesn't return
undefined
.
Example
const reducer = (state = initialState, action) => {
switch (action.type) {
case 'SET_DATA':
debugger // Place a breakpoint for investigation
const result = update(state, {$set: action.data});
// `result` is `undefined` if `action.data` is too
return result;
default:
return state;
}
}
In this case, if you accidentally pass undefined
to action.data
via your action creator then react-addons-update will return the undefined
that came from that variable. Since this overwrites the whole reducer state it will return that undefined
that will trigger the error.
Debugging
You can debug this by examining these places:
- Where the reducer creates the new state. Place a breakpoint into that part to make sure you don't receive or return
undefined
there. - Where the data is passed to the action creator.
ReferenceURL : https://stackoverflow.com/questions/36619093/why-do-i-get-reducer-returned-undefined-during-initialization-despite-pr
'program tip' 카테고리의 다른 글
부적절한 광고 식별자 [IDFA] 사용 (0) | 2020.12.27 |
---|---|
Crashlytics : "비정상 종료를 처리 할 dSYM이 없습니다." (0) | 2020.12.27 |
'\\? \ 파일에서 구성 데이터를 읽으려는'구성 파일을 읽을 수 없습니다. (0) | 2020.12.27 |
Mountain lion 알림 센터에 알림 보내기 (0) | 2020.12.27 |
SQL 내부 조인 둘 이상의 테이블 (0) | 2020.12.27 |