1

I am aware there are a lot of threads referring to this error message but I cannot find one that explains why I am getting this error.

While I am relatively new to React and Redux, I think I understand the concept of Promises and asynch functions but I have to be missing something here. So I have my index.js Modal container, Modal component and a modal reducer.

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

modal reducer: -

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

The problem arises from clicking on: -

<span className='darkBtn' onClick={props.openModal}>

It successfully invokes the reducer action function but also gives me 'Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.' error. I don't understand this because

1) I am using Thunk 2) As this reducer action does not return a promise it is therefore not an asynch function?

I would really appreciate help in resolving this. I've been trying to solve this for a couple hours now and I feel like my eyes are going to start bleeding soon.

skyboyer
  • 22,209
  • 7
  • 57
  • 64
U4EA
  • 832
  • 1
  • 12
  • 27

1 Answers1

0

It's a quirk in JavaScript. The value that you are going to return should be on the same line with the return keyword.

instead of:

// (this will return `undefined`)
export const openModal = () => {
  return
  {
    type: OPEN_MODAL
  }
}

You should write:

//(this will return the action object)
export const openModal = () => {
  return {
    type: OPEN_MODAL
  };
}
banna
  • 239
  • 2
  • 9
  • 1
    Keep it consistent and follow the standard style of opening the brace at the end of the line instead of in a new line. If you really want to use the braces in a new line, you can enclose the object in parentheses. `({ type: OPEN_MODEL })` – nbkhope Oct 12 '17 at 16:32
  • 1
    For more details into why that is happening, see https://stackoverflow.com/questions/3641519/why-does-a-results-vary-based-on-curly-brace-placement – nbkhope Oct 12 '17 at 16:34
  • Awesome, thanks guys. That's it working now. It's nice that, for a change, it was Javascript's typo and not mine haha – U4EA Oct 12 '17 at 21:32
  • @U4EA glad that it's working now :) . You can mark the answer as Accepted answer if it was useful for you. – banna Oct 12 '17 at 22:05
  • 1
    Just accepted it now. I actually don't post here much and didn't know about accepting answers but I am now up to speed with that. Thanks again! – U4EA Oct 13 '17 at 18:53