Reputation: 83
I am little confused with redux and react...
I have parent component(SingleList) that render children component(NutrientsTable). Parent pass to children productList piece of state then children in componentDidMount call action that update currentListNutrients and then I use that in children render() to show.
I tried declare calculateNutrients as just helper method in component and then assign to variable and then use it in render(). As a result, it work fine but i gonna to put all app actions in Action Creator so I need do it with redux.
Parent Comp SingleList
import { connect } from "react-redux";
import NutrientsTable from "../NutrientsTable";
class SingleList extends Component {
render() {
return (
<div className="single-list">
<NutrientsTable
productsList={this.props.list.productsList}
/>
</div>
);
}
}
function mapStateToProps({ lists }, ownProps) {
return {
list: lists[ownProps.match.params.id]
};
}
export default connect(
mapStateToProps,
{}
)(SingleList);
Children Comp NutrientsTable
import { connect } from 'react-redux';
import { calculateNutrients } from '../actions';
class NutrientsTable extends Component {
componentDidMount() {
this.props.calculateNutrients(this.props.productsList);
}
render() {
const { calories, carbohydrates, proteins, fats } = this.props.nutrients;
return (
<div>{calories} {carbohydrates} {proteins} {fats}</div>
)
}
}
const mapStateToProps = ({currentListNutrients}) => {
return { nutrients: currentListNutrients }
}
export default connect(mapStateToProps, { calculateNutrients })(NutrientsTable);
Action calculateNutrients
export function calculateNutrients(productsList) {
let calories = 0,
carbohydrates = 0,
proteins = 0,
fats = 0;
_.map(productsList, product => {
product.calories && (calories += product.calories * product.count);
product.carbohydrates && (carbohydrates += product.carbohydrates * product.count);
product.proteins && (proteins += product.proteins * product.count);
product.fats && (fats += product.fats * product.count);
});
return {
type: CALCULATE_NUTRIENTS,
payload: {calories, carbohydrates, proteins, fats}
}
}
And Reducer just return action.payload
Everything is ok when first render, but when I do some action in parent and change productList piece of state then children doesn't re-render with new productList. I know is it cause componentDidMount call just one. But where i should call action? I cant resolve it with any lifecycle method. Any suggestion?
Upvotes: 0
Views: 193
Reputation: 1577
First, if you're using Redux, you don't have to pass down data from parent to children if data exists on Redux store (application's state). Just use connect
for the children components. The children components should update when detecting any changes in Redux store (application's state).
Second, when you want the changes to happen, you have to dispatch
and action to Redux which tells Redux to call api (or something like that) and update its store.
To handle the api calls, you should use Redux-thunk or Redux-saga.
Upvotes: 1