У меня есть файл, в котором хранятся мои действия redux и редукторы. Я вызываю действие из одного из своих компонентов, но получаю сообщение об ошибке
Error: Given action "GLOBAL_TRIVIA_TAB_CHANGED", reducer "TriviaReducer" returned undefined. To ignore an action, you must explicitly return the previous state. If you want this reducer to hold no value, you can return null instead of undefined.
Это мой файл, в котором лежат мои действия и редукторы
const INITIAL_STATE = {
selectedGlobalTriviaTab: 1,
selectedLocalTriviaTab: 1
}
const GLOBAL_TRIVIA_TAB_CHANGED = 'GLOBAL_TRIVIA_TAB_CHANGED'
const globalTriviaTabChanged = (tab)=> ({
type: GLOBAL_TRIVIA_TAB_CHANGED,
payload: tab
})
const LOCAL_TRIVIA_TAB_CHANGED = 'LOCAL_TRIVIA_TAB_CHANGED'
const localTriviaTabChanged = (tab)=> ({
type: LOCAL_TRIVIA_TAB_CHANGED,
payload: tab
})
export const actions = {
globalTriviaTabChanged,
localTriviaTabChanged
}
export default function TriviaReducer(state = INITIAL_STATE, action){
switch(action.type){
case GLOBAL_TRIVIA_TAB_CHANGED:
state = {...state, selectedGlobalTriviaTab : action.payload};
break;
case LOCAL_TRIVIA_TAB_CHANGED:
state = {...state, selectedLocalTriviaTab: action.payload};
break;
default:
return state
}
}
Я вызываю действия из моего метода рендеринга компонента
import {actions} from "../../store/Trivia";
class TriviaPanel extends Component {
state = {
selectedGlobalTriviaTab: 1
}
toMovies(){
this.setState({selectedGlobalTriviaTab: 1})
}
toPerson(){
this.setState({selectedGlobalTriviaTab: 2})
}
toLocation(){
this.setState({selectedGlobalTriviaTab: 3})
}
render() {
let TabComponent;
if (this.state.selectedGlobalTriviaTab === 1){
TabComponent = <Movies/>
this.props.globalTriviaTabChanged(1) //calling redux-action
}
else if (this.state.selectedGlobalTriviaTab === 2){
TabComponent = <Person/>
//this.globalTriviaTabChanged(2) //calling redux-action
}
return (
<div className = "tabbed-panel">
<div className = "tabs">
<div className = {`tab ${this.state.selectedGlobalTriviaTab === 1? "active" : ""}`} onClick = {this.toMovies.bind(this)}><div className = "tab-inner">MOVIES</div></div>
<div className = {`tab ${this.state.selectedGlobalTriviaTab === 2? "active" : ""}`} onClick = {this.toPerson.bind(this)}><div className = "tab-inner">PERSON</div></div>
<div className = {`tab ${this.state.selectedGlobalTriviaTab === 3? "active" : ""}`} onClick = {this.toLocation.bind(this)}><div className = "tab-inner">LOCATION</div></div>
</div>
{TabComponent}
</div>
);
}
}
const mapDispatchToProps = (dispatch)=> ({
globalTriviaTabChanged(value){
return dispatch(actions.globalTriviaTabChanged(value))
},
localTriviaTabChanged(value){
return dispatch(actions.localTriviaTabChanged(value))
}
})
export default connect(null, mapDispatchToProps)(TriviaPanel)
Вот снимок экрана с ошибкой
Что я делаю неправильно? Обязательно ли мне включать что-нибудь еще в reducer?





Вы напрямую изменяете состояние, а затем ничего не возвращаете в своем редукторе. Вам нужно вернуть новый объект, содержащий ваше состояние и любое новое свойство, которое вы хотите добавить.
switch(action.type){
case GLOBAL_TRIVIA_TAB_CHANGED:
return {...state, selectedGlobalTriviaTab : action.payload};
case LOCAL_TRIVIA_TAB_CHANGED:
return {...state, selectedLocalTriviaTab: action.payload};
default:
return state
}
Нет, это не так. Вы назначаете state = {...}
Кроме того, состояние default: return не запускается, ЕСЛИ НЕ выполняются другие случаи.
Вы не возвращение новое состояние ваших редукторов.
state = {... должен быть return {....
Полный набор изменений:
export default function TriviaReducer(state = INITIAL_STATE, action){
switch(action.type){
case GLOBAL_TRIVIA_TAB_CHANGED:
return {...state, selectedGlobalTriviaTab : action.payload};
break;
case LOCAL_TRIVIA_TAB_CHANGED:
return {...state, selectedLocalTriviaTab: action.payload};
break;
default:
return state
}
}
Вот что я делаю. Верно?