Фильтрация массива объектов в Redux

Основная проблема: два компонента подключены к магазину Redux. Один компонент выполняет повторную визуализацию, а другой — нет при изменении состояния.

Я использую react-redux. У меня есть родительский компонент с именем CART и два дочерних элемента:

  • Фильтр, который представляет собой div, где пользователь может выбирать различные критерии (цвет, размер, пол...)
  • Товары, в которых представлен список обуви

CART.jsx

render() {
    console.log(this.props.filterCart, 'CART')
    const { products, error, pending } = this.props.products
    if (!this.shouldComponentRender()) return <LoadingSpinner />
    return (
        <section className="products_container">
            <Filter />
            {!this.shouldComponentRender() ? (
                <LoadingSpinner />
            ) : (
                <Products
                    products={products}
                    filterCart={this.props.filterCart}
                />
            )}
            {this.props.filterCart[0].value.length > 0 && <h1> hello </h1>}
        </section>
    )
}

const mapStateToProps = state => {
    return {
        products: state.products,
        filterCart: state.filter
    }
}

Мой компонент CART и компонент Filter подключены к моему магазину Redux. Каждый раз, когда пользователи выбирают критерий в компоненте «Фильтр», он отправляется и обновляется в редюсере. Мои рассылки устанавливаются в компоненте «Фильтр».

Я поместил console.log(this.props.filterCart) в render() в своих компонентах CART и Filter. Что я заметил, так это то, что каждый раз, когда выбирается критерий, мой компонент Filter регистрирует изменения, а компонент CART — нет. CART отображает журналы только один раз, и на выходе получается пустой объект. CART не обновляется после внесения изменений.

Для моего второго теста я поместил это в CART & Filter:

{this.props.filterCart[0].value.length > 0 && <h1> hello </h1>}

Всякий раз, когда выбран критерий, мой фильтр отображает "hello", поскольку критерий был добавлен в исходный пустой массив, а CART - нет.

Я провел небольшое исследование и, видимо, это могло быть связано с тем, что я мог изменить начальное состояние в редюсере, что неверно. Но я не уверен, потому что Filter реагирует на изменение.

Это мой код редуктора:

Reducer.js

let filterCriteria = [
    {
        field: 'gender',
        value: []
    },
    {
        field: 'color',
        value: []
    }
]

const filter = (state = filterCriteria, action) => {
    switch (action.type) {
        case FILTER_CRITERIA.FILTER_PRODUCTS_BY_GENDER:
            if (action.indice === true) {
                state[0].value = state[0].value.concat(action.value)
            } else {
                state[0].value = state[0].value.filter(
                    element => element != action.value
                )
            }
            break

        case FILTER_CRITERIA.FILTER_PRODUCTS_BY_COLOR:
            if (action.indice === true) {
                state[1].value = state[1].value.concat(action.value)
            } else {
                state[1].value = state[1].value.filter(
                    element => element != action.value
                )
            }
            break
    }
    return state
}

Просто для уточнения: когда критерий выбран в фильтре (поле ввода отмечено), критерий добавляется в соответствующее поле. Когда я снимаю флажок, он возвращает фильтр без ожидаемого значения. Таким образом, у меня нет никаких проблем с моими редюсерами по этому поводу.

Мои проблемы в том, почему мой второй компонент не перерисовывается.

введите здесь описание изображения

У вас есть идеи, что может быть не так?

Большое спасибо!


person etranger92    schedule 15.12.2019    source источник
comment
У вашего редуктора не должно быть такой логики. Это определенно не очень хорошая практика! Легко заблудиться. Возможно, что состояние не меняется, в этом случае ваш компонент не перерисовывается. Я предлагаю вам реализовать метод жизненного цикла, чтобы увидеть, что происходит. componentWillReceiveProps (nextProps) { console.log ('nextProps', nextProps)}   -  person Gaspar Teixeira    schedule 15.12.2019
comment
Спасибо за ответ, но мое состояние на самом деле меняется. В компоненте фильтра при выборе критерия он автоматически перерисовывается. Потому что через свой console.log я вижу изменения и второй тест пройден. Но корзина не перерисовывается, поэтому мой компонент продуктов не обновляется. Спасибо за ваш ответ и советы.   -  person etranger92    schedule 15.12.2019
comment
Ваш компонент продукта является функциональным компонентом или компонентом класса. Не могли бы вы разместить код здесь?   -  person Gaspar Teixeira    schedule 15.12.2019
comment
Это компонент класса, но продукты только что получили реквизиты от компонента CART, которые являются данными из filterCriteria в моем Store.redux. Это просто отражает ту же проблему из CART, поскольку он получает реквизиты оттуда. Моя проблема заключается в том, почему CART не выполняет повторную визуализацию, когда мой редуктор обновляется. Потому что, если это так, он отобразил бы мой h1 как второй тест {this.props.filterCart[0].value.length › 0 && ‹h1› hello ‹/h1›}, но это не так. Как только я решу это, мои реквизиты для продуктов будут обновлены, так что на самом деле это не проблема, если вы понимаете, что я имел в виду. Извините, если я потерял вас, я новичок.   -  person etranger92    schedule 15.12.2019
comment
Не жалей быть новичком, а сдаться! У меня уже была эта проблема. Теперь я могу тебя понять. Пожалуйста, используйте состояние в вашем Cart.jsx, и с помощью метода componentWillReceiveProps вы устанавливаете значение из редукции в свое состояние, и оно обязательно будет повторно отображаться.   -  person Gaspar Teixeira    schedule 15.12.2019
comment
Я никогда не сдамся :) Я сделал, как вы сказали, но та же проблема. Всякий раз, когда добавляется критерий. Компонент фильтра перерисовывается, поэтому он снова выходит из системы с изменением. Но другие не обновляются. Добавляю фото из console.log Спасибо за терпение.   -  person etranger92    schedule 15.12.2019
comment
Ну потому что значение массива всегда пустое. и вы проверяете, не пусто ли оно, {this.props.filterCart[0].value.length › 0 && ...   -  person Gaspar Teixeira    schedule 15.12.2019
comment
Да, но когда вы добавляете критерий, значение больше не пустое. Итак, в компоненте фильтра тест => ({this.props.filterCart[0].value.length › 0 && ... ) работает, я вижу изменение. Но CART не перерисовывает. :( Это по-прежнему считается пустым значением. Так что, я думаю, оно не обновляется из-за изменения. Я умею создавать такой беспорядок. лол.   -  person etranger92    schedule 15.12.2019
comment
Секундочку, я поделюсь с вами кое-чем на codeandbox   -  person Gaspar Teixeira    schedule 15.12.2019


Ответы (1)


Эй, проверьте эти коды и ящик

Пример React Redux

person Gaspar Teixeira    schedule 15.12.2019
comment
Большое спасибо. Я использовал ваш подход для своего редуктора и смог увидеть изменения в компоненте корзины. Как я прочитал и как подтверждает ваш код, я, должно быть, изменил свое состояние непосредственно в моем предыдущем редукторе, что приводит к тому, что компонент не перерисовывается. Без вашего кода и прежде всего вашего терпения я не смог бы найти решение. Спасибо также тем, кто отредактировал мой пост, чтобы сделать его более понятным, и даже тем, кто думал о решении. Гаспар, спасибо! Благослови тебя Бог - person etranger92; 16.12.2019