无法理解 React Redux 的来源 'Actions must be plain objects.'
Cannot understand source of React Redux 'Actions must be plain objects.'
我知道有很多线程提到此错误消息,但我找不到可以解释为什么我收到此错误的线程。
虽然我对 React 和 Redux 比较陌生,但我想我了解 Promises 和异步函数的概念,但我必须在这里遗漏一些东西。所以我有我的 index.js 模态容器、模态组件和模态缩减器。
index.js:-
import React from 'react'
import ReactDOM from 'react-dom'
import routes from './config/routes'
import {createStore, applyMiddleware, compose, combineReducers} from 'redux'
import {Provider} from 'react-redux'
import * as reducers from '_redux/modules/'
import thunk from 'redux-thunk'
import { checkIfAuthed } from '_helpers/auth'
const store = createStore(
combineReducers(reducers),
compose(applyMiddleware(thunk),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
))
// CSS
import "_css/main.scss";
ReactDOM.render(
<Provider store={store}>{routes}</Provider>,
document.getElementById('app'))
ModalContainer.js:-
import { Modal } from '_components'
import { bindActionCreators } from 'redux'
import * as modalActionCreators from '_redux/modules/Modal/Modal'
import { connect } from 'react-redux'
const mapStateToProps = ({users, modal}) => {
const duckTextLength = modal.duckText.length
return {
user: users[users.authedId] ? users[users.authedId].info : {},
duckText: modal.duckText,
isOpen: modal.isOpen,
isSubmitDisabled: duckTextLength <= 0 || duckTextLength > 140,
}
}
const mapDispatchToProps = (dispatch) => {
return bindActionCreators(modalActionCreators, dispatch)
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Modal)
Modal.js
import React from 'react'
import PropTypes from 'prop-types';
import { default as ReactModal } from 'react-modal'
const modalStyle = {
content: {
width: 350,
margin: '0px auto',
height: 220,
borderRadius: 5,
background: '#EBEBEB',
padding: 0,
}
}
const Modal = (props) => {
const submitDuck = () => {
console.log('Duck', props.duckText)
console.log('user', props.user)
}
return(
<span className='darkBtn' onClick={props.openModal}>
{'Duck'}
</span>
)
}
Modal.PropTypes = {
duckText: PropTypes.string.isRequired,
isOpen: PropTypes.bool.isRequired,
user: PropTypes.object.isRequired,
isSubmitDisabled: PropTypes.bool.isRequired,
openModal: PropTypes.func.isRequired,
closeModal: PropTypes.func.isRequired,
updateDuckText: PropTypes.func.isRequired,
}
export default Modal
模态减速器:-
const OPEN_MODAL = 'OPEN_MODAL'
const CLOSE_MODAL = 'CLOSE_MODAL'
const UPDATE_DUCK_TEXT = 'UPDATE_DUCK_TEXT'
export const openModal = () => {
return
{
type: OPEN_MODAL
}
}
export const closeModal = () => {
return
{
type: CLOSE_MODAL
}
}
export const newDuckText = () => {
return
{
type: UPDATE_DUCK_TEXT,
newDuckText
}
}
const initialState = {
duckText: '',
isOpen: false,
}
export const modal = (state = initialState, action) => {
switch (action.type) {
case OPEN_MODAL :
return {
...state,
isOpen: true,
}
case CLOSE_MODAL :
return {
duckText: '',
isOpen: false,
}
case UPDATE_DUCK_TEXT :
return {
...state,
duckText: action.newDuckText,
}
default :
return state
}
}
问题出现在点击:-
<span className='darkBtn' onClick={props.openModal}>
它成功调用了 reducer 动作函数,但也给我 'Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.' 错误。我不明白这个因为
1) 我正在使用 Thunk
2) 由于此 reducer 操作没有 return 承诺,因此它不是异步函数?
如果能帮助解决这个问题,我将不胜感激。我已经尝试解决这个问题几个小时了,我觉得我的眼睛很快就要开始流血了。
这是 JavaScript 中的一个怪癖。您要 return 的值应该与 return
关键字在同一行。
而不是:
// (this will return `undefined`)
export const openModal = () => {
return
{
type: OPEN_MODAL
}
}
你应该写:
//(this will return the action object)
export const openModal = () => {
return {
type: OPEN_MODAL
};
}
我知道有很多线程提到此错误消息,但我找不到可以解释为什么我收到此错误的线程。
虽然我对 React 和 Redux 比较陌生,但我想我了解 Promises 和异步函数的概念,但我必须在这里遗漏一些东西。所以我有我的 index.js 模态容器、模态组件和模态缩减器。
index.js:-
import React from 'react'
import ReactDOM from 'react-dom'
import routes from './config/routes'
import {createStore, applyMiddleware, compose, combineReducers} from 'redux'
import {Provider} from 'react-redux'
import * as reducers from '_redux/modules/'
import thunk from 'redux-thunk'
import { checkIfAuthed } from '_helpers/auth'
const store = createStore(
combineReducers(reducers),
compose(applyMiddleware(thunk),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
))
// CSS
import "_css/main.scss";
ReactDOM.render(
<Provider store={store}>{routes}</Provider>,
document.getElementById('app'))
ModalContainer.js:-
import { Modal } from '_components'
import { bindActionCreators } from 'redux'
import * as modalActionCreators from '_redux/modules/Modal/Modal'
import { connect } from 'react-redux'
const mapStateToProps = ({users, modal}) => {
const duckTextLength = modal.duckText.length
return {
user: users[users.authedId] ? users[users.authedId].info : {},
duckText: modal.duckText,
isOpen: modal.isOpen,
isSubmitDisabled: duckTextLength <= 0 || duckTextLength > 140,
}
}
const mapDispatchToProps = (dispatch) => {
return bindActionCreators(modalActionCreators, dispatch)
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(Modal)
Modal.js
import React from 'react'
import PropTypes from 'prop-types';
import { default as ReactModal } from 'react-modal'
const modalStyle = {
content: {
width: 350,
margin: '0px auto',
height: 220,
borderRadius: 5,
background: '#EBEBEB',
padding: 0,
}
}
const Modal = (props) => {
const submitDuck = () => {
console.log('Duck', props.duckText)
console.log('user', props.user)
}
return(
<span className='darkBtn' onClick={props.openModal}>
{'Duck'}
</span>
)
}
Modal.PropTypes = {
duckText: PropTypes.string.isRequired,
isOpen: PropTypes.bool.isRequired,
user: PropTypes.object.isRequired,
isSubmitDisabled: PropTypes.bool.isRequired,
openModal: PropTypes.func.isRequired,
closeModal: PropTypes.func.isRequired,
updateDuckText: PropTypes.func.isRequired,
}
export default Modal
模态减速器:-
const OPEN_MODAL = 'OPEN_MODAL'
const CLOSE_MODAL = 'CLOSE_MODAL'
const UPDATE_DUCK_TEXT = 'UPDATE_DUCK_TEXT'
export const openModal = () => {
return
{
type: OPEN_MODAL
}
}
export const closeModal = () => {
return
{
type: CLOSE_MODAL
}
}
export const newDuckText = () => {
return
{
type: UPDATE_DUCK_TEXT,
newDuckText
}
}
const initialState = {
duckText: '',
isOpen: false,
}
export const modal = (state = initialState, action) => {
switch (action.type) {
case OPEN_MODAL :
return {
...state,
isOpen: true,
}
case CLOSE_MODAL :
return {
duckText: '',
isOpen: false,
}
case UPDATE_DUCK_TEXT :
return {
...state,
duckText: action.newDuckText,
}
default :
return state
}
}
问题出现在点击:-
<span className='darkBtn' onClick={props.openModal}>
它成功调用了 reducer 动作函数,但也给我 'Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.' 错误。我不明白这个因为
1) 我正在使用 Thunk 2) 由于此 reducer 操作没有 return 承诺,因此它不是异步函数?
如果能帮助解决这个问题,我将不胜感激。我已经尝试解决这个问题几个小时了,我觉得我的眼睛很快就要开始流血了。
这是 JavaScript 中的一个怪癖。您要 return 的值应该与 return
关键字在同一行。
而不是:
// (this will return `undefined`)
export const openModal = () => {
return
{
type: OPEN_MODAL
}
}
你应该写:
//(this will return the action object)
export const openModal = () => {
return {
type: OPEN_MODAL
};
}