Как обновить рендеринг при обновлении состояния избыточности?

у меня есть код

import React,{Component} from "react"
import {connect} from "react-redux"
class Aside extends Component{
  renderAside(){
    const asideItems = this.props.cart
    console.info(asideItems) // Not Working never
    return asideItems.map((item, key) =>{
      return(
        <div className = "aside-item" key = {key}>
          <div className = "aside-item__name">{item.product.name}</div>
        </div>
      )
    })
  }

  render(){
    return (
      <div>
        {this.renderAside()} 
      </div>
    )
  }

}



const mapStateToProps = (state) => {
  console.info(state.asideReducer.cart) // Working when updated cart
  return{
    cart: state.asideReducer.cart
  }
}

export default connect(mapStateToProps)(Aside)
  

Как сделать так, чтобы при обновлении state.asideReducer.cart мой рендер обновлялся? Например, я нажимаю на другие элементы, и в моей корзине состояний добавляются новые элементы. И когда моя корзина обновится, мне нужно обновить мою сторону (для отображения продуктов в корзине). Большое спасибо.

Возможно, у вас есть где-нибудь работающий образец? Нравится JSFiddle или codeandbox.io?

Rohan Büchner 14.12.2020 07:00
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
1
805
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы должны bind свой renderAside при использовании объявления функции

  1. Первый способ - bind ваша функция перед использованием

    class Aside extends Component {
       constructor(props) {
         super(props);
    
         // This binding is necessary to make `this` work in the callback
         this.renderAside = this.renderAside.bind(this);
       }
    
       // ...
     }
    
  2. Двусторонний - с помощью функции стрелки

     renderAside = () => { // Change this line
         const asideItems = this.props.cart
         console.info(asideItems) // Not Working never
         return asideItems.map((item, key) =>{
           return(
             <div className = "aside-item" key = {key}>
               <div className = "aside-item__name">{item.product.name}</div>
             </div>
           )
         })
       }
    

Пробовал оба варианта, купить не получилось. Я заметил, что если initialState не пуст, рендеринг компонента, т.е. компонент не следует изменениям в избыточности. Но почему?

Dan 14.12.2020 07:50
Ответ принят как подходящий

Поскольку ни в одном из этих компонентов не так много функций, я бы предложил отображать в строке, а не использовать дополнительную функцию (renderAside) для этого процесса. У вас также нет ничего, что требует компонента с состоянием/классом, поэтому я бы предложил изменить его на функциональный компонент, чтобы избежать необходимости в конструкторе. Если вам нужно состояние позже, просто используйте хуки.

Еще одна вещь, которую следует отметить, это то, что с ES6 вы должны использовать стрелочные функции.

renderAside(){ /// change this function to an arrow function
renderAside = () => { /// should be
import React from 'react';
import { connect } from 'react-redux';

const Aside = (props) => {
  let { cart } = props;
  console.info(cart);

  return (
    <div>
      {cart.map((item, key) => {
        return (
          <div className = "aside-item" key = {key}>
            <div className = "aside-item__name">{item.product.name}</div>
          </div>
        );
      })}
    </div>
  );
};

const mapStateToProps = (state) => {
  return {
    cart: state.asideReducer.cart,
  };
};

export default connect(mapStateToProps)(Aside);

В будущем.... Если вы пытаетесь динамически обновлять DOM новыми элементами, вам нужно будет вызвать функцию сопоставления. Вы вызываете его при первом отображении страницы. DOM не будет обновляться только потому, что добавлено что-то новое. Вы должны повторно визуализировать эти данные. В компоненте с состоянием вы должны обновить переменную состояния, а затем вызывать функцию сопоставления каждый раз, когда это состояние было успешно обновлено.

console.info(корзина) . Работает только один раз, когда стартовая страница. У меня есть Redux DevTools, и я вижу, что обновление корзины sideReducer работает правильно, но рендеринг не обновляется. Рендеринг не следует за магазином обновлений в корзину

Dan 14.12.2020 07:55

В этом случае console.info(cart) будет работать только при рендеринге в первый раз. Чтобы просматривать журналы каждый раз, вам нужно будет переместить console.info() в вашу функцию сопоставления непосредственно перед возвратом в DOM. Что касается проблемы сопоставления, удалите ключ из параметров функции сопоставления. Затем вместо key = {key} вы должны использовать key = {item.product.id}, предполагая, что существует идентификатор продукта. Это действует как идентификатор, подобный GUID, в том смысле, что после изменения ключа DOM должен обновиться.

Kota 14.12.2020 08:25

Функция Mapper работает, только если в initialState я кладу какие-то продукты. Например, const initialState = {cart: [ {product:{name: "Test"}, количество: 2}, {product:{name: "Test2"}, количество: 3}, {product:{name: "Test3" } , количество: 42}, {продукт: {имя: "Test4"} , количество: 5}, ] } И работает функция сопоставления. Позже, если я добавлю в состояние новые продукты (и я увижу, какое обновление состояния), функция сопоставления не работает, т.е. рендеринг в элемент запускается один раз, когда компонент рендерится в первый раз

Dan 14.12.2020 08:32

Используете ли вы <Provider> в своем приложении? stackoverflow.com/questions/58249720/…

Kota 14.12.2020 08:48

Я не прав, верните мое новое состояние

Неправильно

return {
        ...state, cart: cart
      }

Правильный код

 return {
        ...state,
        cart: [...state.cart, action.payload]
      }

Другие вопросы по теме