OunknownO
OunknownO

Reputation: 1196

redux multiple connects to one container

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

Answers (1)

natnai
natnai

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

Related Questions