у меня есть код
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 мой рендер обновлялся? Например, я нажимаю на другие элементы, и в моей корзине состояний добавляются новые элементы. И когда моя корзина обновится, мне нужно обновить мою сторону (для отображения продуктов в корзине). Большое спасибо.
Вы должны bind
свой renderAside
при использовании объявления функции
Первый способ - 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);
}
// ...
}
Двусторонний - с помощью функции стрелки
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 не пуст, рендеринг компонента, т.е. компонент не следует изменениям в избыточности. Но почему?
Поскольку ни в одном из этих компонентов не так много функций, я бы предложил отображать в строке, а не использовать дополнительную функцию (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 работает правильно, но рендеринг не обновляется. Рендеринг не следует за магазином обновлений в корзину
В этом случае console.info(cart) будет работать только при рендеринге в первый раз. Чтобы просматривать журналы каждый раз, вам нужно будет переместить console.info() в вашу функцию сопоставления непосредственно перед возвратом в DOM. Что касается проблемы сопоставления, удалите ключ из параметров функции сопоставления. Затем вместо key = {key} вы должны использовать key = {item.product.id}, предполагая, что существует идентификатор продукта. Это действует как идентификатор, подобный GUID, в том смысле, что после изменения ключа DOM должен обновиться.
Функция Mapper работает, только если в initialState я кладу какие-то продукты. Например, const initialState = {cart: [ {product:{name: "Test"}, количество: 2}, {product:{name: "Test2"}, количество: 3}, {product:{name: "Test3" } , количество: 42}, {продукт: {имя: "Test4"} , количество: 5}, ] } И работает функция сопоставления. Позже, если я добавлю в состояние новые продукты (и я увижу, какое обновление состояния), функция сопоставления не работает, т.е. рендеринг в элемент запускается один раз, когда компонент рендерится в первый раз
Используете ли вы <Provider> в своем приложении? stackoverflow.com/questions/58249720/…
Я не прав, верните мое новое состояние
Неправильно
return {
...state, cart: cart
}
Правильный код
return {
...state,
cart: [...state.cart, action.payload]
}
Возможно, у вас есть где-нибудь работающий образец? Нравится JSFiddle или codeandbox.io?