Нужна помощь для моих первых шагов с React-Redux

#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 }.