etranger92
etranger92

Reputation: 67

Filtering an array of objects in Redux

Main issue: Two components are connected to the Redux store. One component re-renders while the other does not when the state changes.

I am using react-redux. I have a parent component named CART and two children:


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
    }
}

My CART component and Filter component are connected to my Redux store. Each time the users select a criteria in the Filter component, it becomes dispatched and updated in the reducer. My dispatches are set in the Filter component.

I put console.log(this.props.filterCart) in the render() in my CART and Filter components. What I noticed is that each time a criteria is selected, my Filter component logs the changes but the CART component doesn't. CART renders only logs one time and the output is an empty object. CART does not seem to be updated when a change has been made.

For my second test, I put this in CART & Filter:

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

Whenever a criteria is selected, my Filter displays "hello" as a criteria has been added to the initial empty array, but CART doesn't.

I did some research and apparently it could be due to the fact that I could have modified the initial state in the reducer, which is wrong. But, I am not sure because Filter reacts to the change.

This my reducer code :

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
}

Just to precise: when a criteria is chosen in the Filter (input box is checked), the criteria is added to the corresponding field. When I uncheck the box, it returns the filter without the value as expected. So, I don't have any concerns with my reducers regarding this matter.

My issues is why my second component doesn't re-render.

enter image description here

Do you have any idea what could be wrong?

Thank you very much!

Upvotes: 0

Views: 3594

Answers (1)

Gaspar Teixeira
Gaspar Teixeira

Reputation: 1267

Hey check this codesandbox

React Redux example

Upvotes: 1

Related Questions