@Incold

Почему не обновляется компонента при изменении props React?

Здравствуйте! Столкнулся с проблемой, при изменении state Redux, родительская компонента обновляется и проблем не вызывает, но её дочерние нет, хотя props передаваемые в них, меняются.
Родительская компонента:
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);


Дочерняя OrderItem (она и не обновляется):
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);


Action:
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
    })
  }
}


Reducer:
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;
  }
}


В итоге получается, что нажимая на кнопку, redux работает правильно, родительская компонента ререндерится, а её дочерние нет. Как это можно исправить?
Заранее, спасибо за любую помошь!
  • Вопрос задан
  • 1057 просмотров
Решения вопроса 1
@dimoff66
Кратко о себе: Я есть
Потому что вы меняете count, но сам элемент заказа не спредите, ссылка остается той же и реакт думает что ничего не изменилось

Вместо
order[index].count = blablabla

напишите
order[index] = {...order[index], count: blablabla }
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы