React-Reudx: Действия должны быть простыми объектами. Использовать пользовательское промежуточное ПО для асинхронных действий - PullRequest
0 голосов
/ 06 мая 2018

Я сделал встречный пример с реактив-редуксом, но, похоже, есть ошибки.

сообщение об ошибке 'Actions must be plain objects. Use custom middleware for async actions.'

А Ошибка Строка

const mapDispatchToProps = dispatch => {
  15 |   return {
> 16 |     handleIncrease: () => dispatch(actions.increase()),
  17 |     handleDecrease: () => dispatch(actions.decrease())
  18 |   };
  19 | };

--------------- = --------------

Сначала actions / actionTypes.js

export const INCREASE = "INCREASE";
export const DECREASE = "DECREASE";

действия / index.js

import * as types from "./actionTypes";

export const increase = number => {
  type: types.INCREASE, number;
};

export const decrease = number => {
  type: types.DECREASE, number;
};

редукторы / index.js

import { combineReducers } from "redux";
import number from "./number";

const reducers = combineReducers({
  number
});

export default reducers;

редукторы / number.js

import * as types from "../actions/actionTypes";

const number = (state = 0, action) => {
  switch (action.type) {
    case types.INCREASE:
      return { ...state, number: action.number + 1 };
    case types.DECREASE:
      return { ...state, number: action.number - 1 };
    default:
      return state;
  }
};

export default number;

компоненты / Counter.js

import React, { Component } from "react";

export default class Counter extends Component {
  render() {
    const { number, onIncrease, onDecrease } = this.props;
    return (
      <div>
        <h1>Counter</h1>
        <div>Value: {number}</div>
        <button onClick={onIncrease}>+</button>
        <button onClick={onDecrease}>-</button>
      </div>
    );
  }
}

Last, App.js

import React, { Component } from "react";
import "./App.css";
import Counter from "./components/Counter";

import { connect } from "react-redux";
import * as actions from "./actions";

const mapStateToProps = state => {
  return {
    number: state.number
  };
};

const mapDispatchToProps = dispatch => {
  return {
    handleIncrease: () => dispatch(actions.increase()),
    handleDecrease: () => dispatch(actions.decrease())
  };
};

class App extends Component {
  render() {
    return (
      <div className="App">
        <Counter
          number={this.props.number}
          onIncrease={this.props.handleIncrease}
          onDecrease={this.props.handleDecrease}
        />
      </div>
    );
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(App);

Какая часть не так? Мне тоже любопытно.

Спасибо.

  • Я исправляю эту ошибку, но затем появляется новая ошибка

ошибка сообщение

Uncaught Error: Objects are not valid as a React child (found: object with keys {number}). If you meant to render a collection of children, use an array instead.
in div (at Counter.js:9)
in div (at Counter.js:7)
in Counter (at App.js:25)
in div (at App.js:24)
in App (created by Connect(App))
in Connect(App) (at index.js:16)
in Provider (at index.js:15)
at invariant (invariant.js:42)
at throwOnInvalidObjectType (react-dom.development.js:7362)
at updateSlot (react-dom.development.js:7631)
at reconcileChildrenArray (react-dom.development.js:7762)
at reconcileChildFibers (react-dom.development.js:8121)
at reconcileChildrenAtExpirationTime (react-dom.development.js:8248)
at reconcileChildren (react-dom.development.js:8231)
at updateHostComponent (react-dom.development.js:8539)
at beginWork (react-dom.development.js:8986)
at performUnitOfWork (react-dom.development.js:11814)
at workLoop (react-dom.development.js:11843)
at HTMLUnknownElement.callCallback (react-dom.development.js:100)
at Object.invokeGuardedCallbackDev (react-dom.development.js:138)
at invokeGuardedCallback (react-dom.development.js:187)
at replayUnitOfWork (react-dom.development.js:11318)
at renderRoot (react-dom.development.js:11885)
at performWorkOnRoot (react-dom.development.js:12449)
at performWork (react-dom.development.js:12370)
at performSyncWork (react-dom.development.js:12347)
at interactiveUpdates (react-dom.development.js:12597)
at interactiveUpdates (react-dom.development.js:1958)
at dispatchInteractiveEvent (react-dom.development.js:4259)

Ответы [ 2 ]

0 голосов
/ 06 мая 2018

Я никогда не вижу, чтобы вы использовали bindActionCreators. Пример

const {createStore, bindActionCreators} = Redux;
const {Component} = React;
const { connect, Provider } = ReactRedux;

const TestClicker = (props) => {
  return(
    <button onClick={props.onClick}>Click Me</button>
  )
}

class App extends React.Component {
  constructor(){
    super();
}

render(){
   return(
    <div>
      <h1>Hello</h1>
      <p>{this.props.work}</p>
      <TestClicker onClick={this.props.testAction}/>
      <TestClicker onClick={this.props.testAction2}/>
      <TestClicker onClick={this.props.testAction3}/>
    </div>
   );
  }
}

function mapStateToProps(state){
  return {
    work: state.working
  }
}

function mapDispatchToProps(dispatch){
  return bindActionCreators({
    testAction: changeAc1,
    testAction2: changeAc2,
    testAction3: changeAc3
  }, dispatch);
}

App = connect(mapStateToProps, mapDispatchToProps)(App);

const changeAc1 = (action) => {
  console.log("I've been clicked");
  return {
    type: "GO"
  }
}

const changeAc2 = (action) => {
  console.log("I've been clicked");
  return {
    type: "YES"
  }
}

const changeAc3 = (action) => {
  console.log("I've been clicked");
  return {
    type: "GLOW"
  }
}

const initialState = { working: "no" };

const reducer = (state, action) => {
  switch(action.type){
    case "GO":
      return Object.assign({}, state, { working: "yes" });
    case "YES":
      return Object.assign({}, state, { working: "HELL YESSS!!!" });
    case "GLOW":
      return Object.assign({}, state, { working: "This is the SHIIIIIIIIZZZZZ" });
    default:
      return state;
  }
}

const store = createStore(reducer, initialState);

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

Ссылка на codepen https://codepen.io/ar-traunworks/pen/MrNYqX Вы либо изменяете состояние (пытаетесь сохранить число в переменной, вернуть целое состояние ... состояние, а затем изменить свойство number в этом примере {... состояние, число: (переменная)}), либо вам нужно проверить, как Вы связали свои действия.

0 голосов
/ 06 мая 2018

Вы ничего не возвращаете здесь:

export const increase = number => {
  type: types.INCREASE, number;
};

export const decrease = number => {
  type: types.DECREASE, number;
};

Исправьте это, фактически вернув объект:

export const increase = number => {
  return {
    type: types.INCREASE, number
  }
};

export const decrease = number => {
  return {
    type: types.DECREASE, number
  }
};

или более краткий:

export const increase = number => ({
  type: types.INCREASE, number;
});

export const decrease = number => ({
  type: types.DECREASE, number;
});

EDIT:

Вам также нужно починить редуктор:

const number = (state = 0, action) => {
  switch (action.type) {
    case types.INCREASE:
      return state + 1;
    case types.DECREASE:
      return state - 1;
    default:
      return state;
  }
};

состояние является единственным числом, поэтому вам не нужно копировать какие-либо значения. Вы возвращали объект из вашего редуктора, поэтому реакция не могла сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...