Reputation: 1196
I have two reducers I want to use both of them in one container but it only pulls from one
this is where reducers combine
import { combineReducers } from "redux"
import cityName from "./weather-apiReducers"
import nameOfCity from "./weather-apiReducers"
import weatherDescription from "./weather-apiReducers"
import windSpeed from "./weather-apiReducers"
import temperature from "./weather-apiReducers"
import maxTemperature from "./weather-apiReducers"
import minTemperature from "./weather-apiReducers"
import isClicked from "./weather-apiReducers"
import name from "./weather-apiReducers"
export default combineReducers({
cityName,
nameOfCity,
weatherDescription,
windSpeed,
temperature,
maxTemperature,
minTemperature,
isClicked,
name
})
reducers
export default function reducer(state={
nameOfCity: "",
weatherDescription: "",
windSpeed: "",
temperature: "",
maxTemperature: "",
minTemperature: "",
}, action) {
switch (action.type){
case "FETCH_WEATHER_DATA": {
return {...state,
fetching: true
}
}
case "FETCH_WEATHER_REJECTED": {
return {...state,
fetching: false,
error: action.data
}
}
case "FETCH_WEATHER_DATA_FULFILLED": {
return {...state,
fetching: false,
fetched: true,
nameOfCity: action.results.city.name,
weatherDescription: action.results.list[0].weather[0].description,
windSpeed: action.results.list[2].wind.speed,
temperature: action.results.list[0].main.temp,
maxTemperature: action.results.list[0].main.temp_max,
minTemperature: action.results.list[0].main.temp_min
}
}
case "UPDATE_INFO_DATA_FULFILLED": {
return {...state,
nameOfCity: action.results.cityName,
}
}
case "HANDLE_CITY_NAME": {
return {...state,
cityName: action.value,
}
}
}
return state;
}
export function reducerAList(state={
id: "",
name: ""
}, action) {
switch (action.type){
case "FETCH_A_DATA": {
return {...state,
fetching: true
}
}
case "FETCH_A_REJECTED": {
return {...state,
fetching: false,
error: action.data
}
}
case "FETCH_A_DATA_FULFILLED": {
return {...state,
fetching: false,
fetched: true,
name: action.resultsP.name
}
}
}
return state;
}
store
import { applyMiddleware, createStore } from "redux"
import logger from "redux-logger"
import thunk from "redux-thunk"
import promise from "redux-promise-middleware"
import reducer, {reducerAList} from "./reducers"
const middleware = applyMiddleware(thunk, promise(), logger())
export default createStore( reducer, reducerAList, middleware)
container
import React, { Component } from 'react';
import './App.css';
import {FormContainer} from './containers/FormContainer';
import WeatherInfo from './components/WeatherInfo';
import {fetchWeatherData} from "./actions/weather-apiActions";
import {fetchAList} from "./actions/weather-apiActions";
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,
name:store.name
}
})
This console log inside container for name gives undefined but for rest of the variables it gives what is given in connect. It's not listening for name variable at all. My question is how to connect this second reducer with container
render() {
const { cityName, nameOfCity, weatherDescription, windSpeed, temperature, maxTemperature, minTemperature, name} = this.props;
console.log(name);
}
Upvotes: 0
Views: 1116
Reputation: 564
You've made several errors here. Let's dive in.
Firstly, name
is not even exported from the module weather-apiReducers
.
Let's see what's exported from it:
export default reducer ...
, and,
export reducerAList ...
.
When you then try to do the following:
import name from './weather-apiReducers
, in reality, name
resolves to that module's default
export. Therefore, when you include it in your call to combineReducers
, in reality, you are passing the same function (the default
export), twice.
The second mistake you made is a fundamental misunderstanding of how a reducer works in Redux.
In Redux, state is stored in a single atomic object. Each reducer you pass to combineReducers
gets a key which corresponds to the last state object returned by that reducer.
According to the docs:
The combineReducers helper function turns an object whose values are different reducing functions into a single reducing function you can pass to createStore.
The resulting reducer calls every child reducer, and gathers their results into a single state object. The shape of the state object matches the keys of the passed reducers.
Since you, in reality, only passed two reducer functions to combineReducers
, you only got back two state keys.
Also, a reducer is just a function that returns an object, that then forms part of the redux store. You should only import
and export
these, not the state they produce. If you wish to have more keys, you need to make a reducer function for every key you want to have.
If I've guessed your intentions correctly, what you should in fact do is split up reducer
and reducerAList
into reducer functions for each of cityName, nameOfCity, weatherDescription, windSpeed, name
etc. You'll then be able to access a separate state object for each of them in your container component which you created with connect
.
Upvotes: 3