Я получаю сообщение об ошибке: «react-dom.development.js: 55 Uncaught Invariant Violation: объекты недействительны в качестве дочернего элемента React (найдено: объект с ключами {counter}). Если вы хотели отобразить коллекцию дочерних элементов, вместо этого используйте массив».
Это происходит, когда я меняю Counter.js с <p>{this.state.counter}</p> на <p>{this.props.counter}</p>
Насколько я понимаю, я использую mapStateToProps и mapDispatchToProps, и я должен иметь возможность получить хотя бы начальное состояние счетчика, равное 0.
Я не уверен, является ли это причиной проблемы, но я использую console.info для просмотра того, как выглядит состояние, но не уверен, что это правильно:
{counter: {…}}
counter: {counter: 0}
__proto__: Object
Counter.js
// Imports: Dependencies
import React, { Component } from 'react';
import { connect } from 'react-redux';
// Imports: Action Types
import { INCREASE_COUNTER, DECREASE_COUNTER } from '../actionTypes/index';
// Component: Counter
class Counter extends React.Component {
constructor(props) {
super(props);
this.state = {
counter: 0,
};
}
render() {
return (
<div>
<h2>React Redux Counter</h2>
<button type = "button" onClick = {() => this.props.increaseCounter()}>Increase</button>
<p>{this.props.counter}</p>
<button type = "button" onClick = {() => this.props.decreaseCounter()}>Decrease</button>
</div>
);
}
}
// Map State To Props (Reducers)
const mapStateToProps = (state) => {
console.info('State:');
console.info(state);
console.info('');
return {
counter: state.counter,
};
};
// Map Dispatch To Props (Actions)
const mapDispatchToProps = (dispatch) => {
return {
increaseCounter: () => dispatch({ type: INCREASE_COUNTER }),
decreaseCounter: () => dispatch({ type: DECREASE_COUNTER }),
};
};
// Exports
export default connect(mapStateToProps, mapDispatchToProps)(Counter);
App.js
// Imports: Dependencies
import React, { Component } from 'react';
// Imports: Components
import Counter from './components/Counter';
// React Application
class App extends Component {
render() {
return (
<div>
<Counter />
</div>
);
}
}
// Exports
export default App;
index.js
// Imports: Dependencies
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store/store';
// Imports: React Application
import App from './App';
// Render App
ReactDOM.render(
<Provider store = {store}>
<App />
</Provider>,
document.getElementById('app'),
);
store.js
// Imports: Dependencies
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import { createLogger } from 'redux-logger';
// Imports: Redux
import rootReducer from '../reducers/index';
// Redux: Thunk (Async/Await)
const middleware = [thunk];
if (process.env.NODE_ENV !== 'production') {
middleware.push(createLogger());
}
// Redux: Store
const store = createStore(
rootReducer,
applyMiddleware(...middleware),
);
// Exports
export default store;
counterReducer.js
import { INCREASE_COUNTER, DECREASE_COUNTER } from '../actionTypes/actionTypes';
// Initial State
const initialState = {
counter: 0,
};
// Redux: Counter Reducer
const counterReducer = (state = initialState, action) => {
switch (action.type) {
case INCREASE_COUNTER: {
return {
...state,
counter: state.counter + 1,
};
}
case DECREASE_COUNTER: {
return {
...state,
counter: state.counter - 1,
};
}
default: {
return state;
}
}
};
// Exports
export default counterReducer;
actionTypes.js
export const INCREASE_COUNTER = 'INCREASE_COUNTER';
export const DECREASE_COUNTER = 'DECREASE_COUNTER';





Ваше состояние устроено следующим образом:
{
counter: {
counter : 0
}
}
Он структурирован таким образом, потому что ваш counterReducer определяет вложенное поле с именем counter, а затем counterReducer объединяется в более крупный объект, потому что он передается combineReducers({counter : counterReducer}).
В вашем компоненте вы визуализируете:
<p>{this.props.counter}</p>
Но props.counter будет объектом, как {counter : 0}.
React не позволит вам просто вставить объект в вывод рендеринга — он не знает, что с ним делать.
Если вы просто хотите показать значение счетчика, то оно должно быть:
<p>{this.props.counter.counter}</p>
Другим вариантом было бы изменить ваш mapStateToProps на:
const mapStateToProps = (state) => {
return {
counter: state.counter.counter,
};
};
Третий вариант — изменить counterReducer так, чтобы он отслеживал только само число как аргумент state редуктора, а не вкладывал это значение в объект.
Я знал, что склоняюсь в правильном направлении, но не был уверен. Спасибо за помощь и разъяснения!