#redux
#redux
Вопрос:
Я изо всех сил пытаюсь сделать свои первые шаги с Redux. Все эти руководства «Todo-App» хороши, как и руководства «Увеличить кнопку». Я думал о том, чтобы на собственном примере научить себя логике Redux, но что-то не работает. На данный момент я не уверен, откуда берется состояние, поэтому я перепробовал множество разных вариантов, чтобы Redux «запустился» без ошибок инициализации, и я нашел рабочее решение! Во-первых, я просто настроил состояние в редукторе, но кнопка-описание не появилась. Затем я дополнительно настроил состояние в хранилище, и, по крайней мере, на кнопке есть описание test123 и консоль.журнал сработал. Но как получить состояние из редуктора (я проверил документацию, и было рекомендовано передавать состояние редукторами, а не самим хранилищем). На данный момент я получаю следующую ошибку:
Error: Objects are not valid as a React child (found: object with keys {0, 1, 2, 3}). If you meant to render a collection of children, use an array instead.
Вот мой абсолютно базовый код, который должен помочь мне понять логику redux:
Тип действия:
export const CLICK = 'CLICK'
Создатель действия:
import { CLICK } from './types';
export function clicked() {
return({
type: CLICK,
payload: 'switch the describtion of the button'
})
}
создатель кликов:
import { CLICK } from '../actions/types';
const initialState = {
name: 'test'
}
export default function (state = initialState, action) {
console.log('click-test', action)
switch(action.type) {
case CLICK: {
return Object.assign({}, state)
}
default:
return state
}
}
корнередуктор:
import { combineReducers } from 'redux';
import clickReducer from './clickReducer';
export default combineReducers({
name: clickReducer
})
хранилище:
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
const initialState = {
name: 'test123'
};
const middleWare = [thunk];
const store = createStore(rootReducer, initialState, applyMiddleware(...middleWare));
export default store;
и кнопка-компонент:
import React, { Component } from 'react'
import { connect } from 'react-redux';
import { clicked } from '../actions/clickAction';
class Button extends Component {
render() {
return (
<div>
<button onClick={this.props.clicked}>{this.props.name}</button>
</div>
)
}
}
const mapStateToProps = state => ({
name: state.name
});
export default connect(mapStateToProps, { clicked })(Button);
Было бы очень приятно получить некоторую помощь с этой проблемой, чтобы иметь возможность предпринять дальнейшие шаги в Redux.
Спасибо!
Комментарии:
1. Я немного запутался в том, чего ты пытаешься достичь. Вы можете получить состояние своего хранилища через
mapStateToProps
, и, похоже, вы настроили его правильно. Единственная проблема, с которой я сталкиваюсь с вашим кодом, заключается в том, что вы,clickReducer
похоже, не обновляете свой магазин (или, возможно, он отличается от метода, который я использую), и вашеclicked
действие не должно вызыватьсяonClick
таким образом. Можете ли вы уточнить, в чем на самом деле заключается ваша проблема? Похоже, я нажал кнопку, и состояние не будет обновляться?2. onClick работает таким образом, но состояние не меняется, поэтому кнопка по-прежнему остается описанной «name» вместо test. :((((((
Ответ №1:
Вам не нужны круглые скобки, сделайте это вместо этого:
import { CLICK } from './types';
export clicked = () => {
return {
type: CLICK,
payload: 'switch the describtion of the button'
}
}
Ваш тип «CLICK» в инструкции switch не обновляет имя, вы просто возвращаете состояние. Сделайте это вместо:
import { CLICK } from '../actions/types';
const initialState = {
name: 'test'
}
export default (state = initialState, action) => {
switch(action.type) {
case CLICK:
return {
...state,
name: action.payload
}
default:
return state
}
}
В вашем хранилище слишком много информации, сделайте это вместо:
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
const store = createStore(
rootReducer,
applyMiddleware(thunk)
);
export default store;
Вызовите свойство объекта:
import React, { Component } from 'react'
import { connect } from 'react-redux';
import { clicked } from '../actions/clickAction';
class Button extends Component {
render() {
return (
<div>
<button onClick={this.props.clicked}>{this.props.name.name}</button>
</div>
)
}
}
const mapStateToProps = state => ({
name: state.name
});
export default connect(mapStateToProps, { clicked })(Button);
Ответ №2:
это решение, касающееся редуктора, по-прежнему приводит к следующей ошибке:
Error: Objects are not valid as a React child (found: object with keys {0, 1, 2, 3}). If you meant to render a collection of children, use an array instead.
in button (at button.js:9)
in div (at button.js:8)
in Button (created by ConnectFunction)
in ConnectFunction (at App.js:12)
in div (at App.js:11)
in Provider (at App.js:10)
in App (at src/index.js:6) react-dom.development.js:57
React 15
dispatchInteractiveEvent self-hosted:1029
Я действительно не могу представить, почему это так, потому что мое решение выглядит нормально, и это очень примитивное приложение для изменения описания кнопки :(((
Комментарии:
1. Торстен, на Button.js файл попробуйте это: { this.props.name.name }.