我用react-redux做了一个反例,但似乎有错误。
错误消息为'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>
);
}
}
最后, 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)
答案 0 :(得分:3)
你不会在这里退回任何东西:
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;
});
编辑:
您还需要修复reducer:
const number = (state = 0, action) => {
switch (action.type) {
case types.INCREASE:
return state + 1;
case types.DECREASE:
return state - 1;
default:
return state;
}
};
州是唯一的号码,因此您不需要复制任何值。你正在从你的减速器返回一个物体,这就是为什么反应无法渲染它。
答案 1 :(得分:0)
我从未见过你使用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的链接 你要么改变状态(尝试在变量中存储数字,返回整个状态......状态,然后数字属性变异,例如{...状态,数字:(变量)})或者你需要检查如何你把行动绑定了。