Answer the question
In order to leave comments, you need to log in
Why doesn't the component update when React props change?
Hello! I ran into a problem, when the state of Redux changes, the parent component is updated and does not cause problems, but its children do not, although the props passed to them change.
Parent component:
function Basket(props) {
return (
<div className="d-flex flex-fill" id="basket">
<div className="row container-fluid">
<div className="col">
<h4 className="display-4">Your order:</h4>
<hr className="m-2"/>
{
this.props.order.map(item => {
console.log(item); // Здесь всё хорошо, item (item.count) приходит новый
// item - это объект, имеющий структуру {orderPizza: {...}, count: Number}
// и ниже буде код action, который меняет item.count
return <OrderItem key={item.orderPizza._id} pizzaData={item} />
})
}
<Link type="button" className="btn btn-warning my-3" to="/menu">Return to menu</Link>
</div>
<div className="col"></div>
</div>
</div>
)
}
export default connect(
state => ({
order: state.basket.order,
//count: state.basket.count,
total: state.basket.total,
currency: state.menu.currency
}),
null
)(Basket);
function OrderItem(props) {
const {orderPizza, count} = props.pizzaData;
console.log(count); // тут при рендере, должно выводится количество, которое приходит из props, но при их изменении это не срабатывает, из чего я делаю вывод, что ререндер не произошёл
return (
<div className="row d-flex align-items-center orderItem my-2">
<div className="col-3">
<img src={images(`./${orderPizza.pizzaName}.jpg`)} alt="pizza"/>
</div>
<div className="col-3 text-center orderItemInfo">
<div className="font-italic">{orderPizza.pizzaName}</div>
</div>
<div className="col-2">
<div className="row p-0">
<div className='col d-flex justify-content-center align-items-center pl-0'>
<button className="btn btn-outline-success rounded-circle btn-sm"
onClick={() => props.changeCount('plus', orderPizza._id)}
>
<i className="fa fa-plus"></i>
</button>
</div>
<div className='col text-center orderItemInfo p-0'>
<div>{count}</div>
</div>
<div className='col d-flex justify-content-center align-items-center pr-0'>
<button className="btn btn-outline-danger rounded-circle btn-sm"
onClick={() => props.changeCount('minus', orderPizza._id)}
>
<i className="fa fa-minus"></i>
</button>
</div>
</div>
</div>
<div className="col-3 text-center orderItemInfo">
<div>{(orderPizza.price*props.currency.rate*count).toFixed(2)} <i className={`fa ${props.currency.symbol}`}></i></div>
</div>
<div className="col-1 text-center pl-0">
<button className="btn"><i className="fa fa-close fa-2x"></i></button>
</div>
</div>
)
}
export default connect(
state => ({
currency: state.menu.currency
}),
dispatch => ({
changeCount(type, id) { // Этот action должен менять количество при нажатии на кнопку, он работает корректно, но происходит вышеописанная ситуация
dispatch(changePizzaCount(type, id))
}
})
)(OrderItem);
export const changePizzaCount = (type, id) => {
return (dispatch, getState) => {
const order = getState().basket.order;
let index = order.findIndex(item => item.orderPizza._id === id);
order[index].count =
type === 'plus'
? order[index].count + 1
: order[index].count - 1 < 1
? 1
: order[index].count - 1;
return dispatch({
type: 'CHANGE_PIZZA_COUNT',
order: order,
pizzaPrice: type === 'plus' ? order[index].orderPizza.price : -order[index].orderPizza.price
})
}
}
const initialState = {
total: 0,
count: 0, // этот count, отвечает за количество позиций в корзине, не обращайте на него внимания
order: []
};
export default function basket(state=initialState, action) {
switch (action.type) {
...
case 'CHANGE_PIZZA_COUNT':
return {
...state,
total: state.total + action.pizzaPrice,
order: [...action.order]
}
default:
return state;
}
}
Answer the question
In order to leave comments, you need to log in
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question