OunknownO OunknownO -4 years ago 194
React JSX Question

Uncaught TypeError: Cannot read property 'type' of undefined at start of switch function

I'm trying to use move my app to redux-react from pure react. I made an action and reducer for onClick but after trying to start the app in dev mode I get this error

Uncaught TypeError: Cannot read property 'type' of undefined at reducerDomMethods (manMethodsReducers.js:12)


which is this line

switch (action.type) {


This is my code

reducer

export default function reducerDomMethods(state={
isClicked: false,
}, action) {
switch (action.type) {
case "CLICK_OPEN": {
return {
...state,
isClicked: true
}
}

case "CLICK_CLOSE": {
return{
...state,
isClicked:false
}
}

return state;
}
}


action

export function clicking(isClicked) {

return function (dispatch) {

if( isClicked === true){
dispatch({type: "CLICK_OPEN",isClicked: true});
}else {
dispatch({type: "CLICK_CLOSE",isClicked: false});
}
}
}


combine reducer

import { combineReducers } from "redux"

import cityName from "./apiReducers"
import nameOfCity from "./apiReducers"
import weatherDescription from "./apiReducers"
import windSpeed from "./apiReducers"
import temperature from "./apiReducers"
import maxTemperature from "./apiReducers"
import minTemperature from "./apiReducers"
import isClicked from "./manMethodsReducers"

export default combineReducers({
cityName,
nameOfCity,
weatherDescription,
windSpeed,
temperature,
maxTemperature,
minTemperature,
isClicked
})


store

import { applyMiddleware, createStore } from "redux"

import logger from "redux-logger"
import thunk from "redux-thunk"
import promise from "redux-promise-middleware"

import reducer from "./reducers"
import reducerDomMethods from "./reducers"

const middleware = applyMiddleware(promise(), thunk, logger())

export default createStore( reducer , reducerDomMethods, middleware)


connect

import {connect} from "react-redux"

@connect((store) => {

return {
nameOfCity:store.nameOfCity.nameOfCity,
weatherDescription:store.weatherDescription.weatherDescription,
windSpeed:store.windSpeed.windSpeed,
temperature:store.temperature.temperature,
maxTemperature:store.maxTemperature.maxTemperature,
minTemperature:store.minTemperature.minTemperature,
isClicked:store.isClicked.isClicked,
}
})


EDIT: This is where I am importing sending the action

import React, {Component} from 'react';
import SearchBar from '../components/SearchBar';
import {connect} from "react-redux"
import {fetchWeatherData} from "../actions/weather-apiActions";
import {clicking} from '../actions/manMethodsActions'

@connect((store) => {
return {
nameOfCity:store.nameOfCity.nameOfCity,
weatherDescription:store.weatherDescription.weatherDescription,
windSpeed:store.windSpeed.windSpeed,
temperature:store.temperature.temperature,
maxTemperature:store.maxTemperature.maxTemperature,
minTemperature:store.minTemperature.minTemperature,
isClicked:store.isClicked.isClicked,
}
})

class FormContainer extends Component {

handleFormSubmit(e) {
e.preventDefault();
var cName = e.target.CityName.value;
console.log(cName);
let isClicking = false;
this.props.dispatch(clicking(isClicking));
this.props.dispatch(fetchWeatherData(cName));
}

render() {

return (


<div>
<form onSubmit={this.handleFormSubmit.bind(this)}>
<label>{this.props.label}</label>


<SearchBar
name="CityName"
type="text"
value={this.props.cityName}
placeholder="search"
/>

<button type="submit" className="" value='Submit' placeholder="Search">Search</button>
</form>
</div>
);
}
}

export {FormContainer};

Answer Source

Your clicking action returns a function and you are dispatching that function with this.props.dispatch(clicking(isClicking));. If you want to keep the nested structure of the action then you should modify the dispatch to this.props.dispatch(clicking(isClicking)()); which automatically calls the function received from clicking action.

However, the recommended use would be to modify your clicking action...

export function clicking(isClicked) {
  dispatch({ type: "CLICK_OPEN", isClicked });
}

Bear in mind that you can import your store in the actions file and use store.dispatch to dispatch an action. You do not need to pass the dispatch function from the component.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download