I'm trying to pass props to multiple components using react-redux. The data that I'm receiving and trying to pass is from a database, so asynchronicity is involved. Because props isn't defined when it hits the component, my app is throwing an undefined error. After it throws the error in the component, it continues to resolve state, but Once state is defined, it doesn't rerender the component with the new props. Another nugget...I'm using combineReducers. Before using combineReducers (just using the baby-reducer) I didn't have this problem. It started after I made another reducer and combined it with (baby-reducer) Any idea what is going on here? Why won't my component re-render?
Here is my container that is rendering components:
import React,{Component} from 'react'
import store from '../store'
import {connect} from 'react-redux';
import BabyProfile from '../components/BabyProfile'
import Weight from '../components/Weight'
import Height from '../components/Height'
import Feed from '../components/Feed'
import Sleep from '../components/Sleep'
import Diaper from '../components/Diaper'
class BabyProfileContainer extends Component {
render(){
// console.log("RENDER PROPS", this.props)
const {baby, weight, height, feed, sleep, diapers} = this.props
return(
<div>
<BabyProfile baby={baby}/>
<Weight weight={weight}/>
<Height height={height}/>
<Feed feed={feed}/>
<Sleep sleep={sleep}/>
<Diaper diapers={diapers}/>
</div>
)
}
}
const mapStateToProps = (state, ownProps) => {
// console.log("MSTP Baby Container", state, "OWN PROPS", ownProps)
return {
baby: state.baby,
diapers: state.diapers,
weight: state.weight,
height: state.height,
sleep: state.sleep,
feed: state.feeding
}
}
export default connect(mapStateToProps)(BabyProfileContainer)
here is my baby-reducer:
import {RECEIVE_BABY} from '../constants'
const initialBabyState = {
baby: {},
diapers: [],
weight: [],
height: [],
feeding: [],
sleep: []
}
export default function(state = initialBabyState, action){
console.log('BABY REducer')
const newState = Object.assign({}, state)
switch (action.type){
case RECEIVE_BABY:
newState.baby = action.baby;
newState.diapers = action.diapers
newState.weight = action.weight;
newState.height = action.height;
newState.feeding = action.feeding;
newState.sleep = action.sleep
break;
default:
return state
}
return newState
}
here is my combinedReducer:
import {combineReducers} from 'redux'
import baby from './baby-reducer'
import parent from './parent-reducer'
export default combineReducers({
baby,
parent
})
Here is my weight component:
import React from 'react';
import {Line} from 'react-chartjs-2'
export default function(weight){
console.log("IN WEIGHT", weight)
var weightArr = weight.weight
const weightData = {
labels: weightArr.map(instance=>instance.date.slice(0,10)),
datasets:[{
label: "baby weight",
backgroundColor: 'rgba(75,192,192,1)',
data: weightArr.map(instance =>(instance.weight))
}]
}
const options ={
maintainAspectRatio: false,
xAxes: [{
stacked: true,
ticks: {
beginAtZero:true
}
}],
yAxes: [{ticks: {
beginAtZero:true
}
}]
}
return (
<div className="baby">
<div>
<h3>I'm In weight component</h3>
</div>
<div className="weight"></div>
{
weightArr.map((weight,index) => (
<div key={index}>
<span>{ weight.weight}</span>
</div>
))
}
<div className="Chart">
<Line data={weightData} width={200} height={200} options={options}/>
</div>
</div>
);
}
Here is my action creator:
import {RECEIVE_BABY} from '../constants'
import axios from 'axios'
export const receiveBaby = (baby,weight,height,sleep,diaper,feeding) =>({
type: RECEIVE_BABY,
baby: baby,
weight: weight,
feeding: feeding,
height: height,
sleep: sleep,
diapers: diaper
})
export const getBabyById = babyId => {
console.log("GET BABY BY ID")
return dispatch => {
Promise
.all([
axios.get(`/api/baby/${babyId}`),
axios.get(`/api/baby/${babyId}/weight`),
axios.get(`/api/baby/${babyId}/height`),
axios.get(`/api/baby/${babyId}/sleep`),
axios.get(`/api/baby/${babyId}/diaper`),
axios.get(`/api/baby/${babyId}/feed`)
])
.then(results => results.map(r => r.data))
.then(results => {
console.log("THIS IS RESULTS in Action assadkjasdfkjl;", results)
dispatch(receiveBaby(...results));
})
.catch(function(err){
console.log(err)
})
};
};
Here is a snapshot from chrome devTools of the error and the subsequent state
any help would be greatly appreciated. Thanks!
I believe this is linked to the fact that when you combine the reducers you need to include them in the
mapStateToProps
in the following way:Basically, you have to make sure the appropriate reducer is connected here.