¿Por qué mi componente de reacción no se vuelve a renderizar después de enviar una acción que cambia la tienda redux?

0

Solo estoy jugando con Redux, lo siento por los errores o las malas prácticas.

Básicamente, tengo una lista de partes de la computadora que el usuario puede seleccionar / deseleccionar. Cada parte es un objeto JS que tiene id, nombre, precio y campo seleccionado:

const initialState = {
    products: [
        {product_id: 0, product_name: "Hard Drive 320 GB 5400 RPM", price: 1450, selected: false},
        {product_id: 1, product_name: "Solid State Drive 128 GB R/W - 420 MB/s", price: 1880, selected: false},
        {product_id: 2, product_name: "Gigabyte MB A270S AM4 DDR4 3200HZ OC HDMI/VGA/DVI", price: 3560, selected: false},
        {product_id: 3, product_name: "Asus MB A420M LGA 1151 3200HZ OC HDMI/VGA", price: 3660, selected: false},
        {product_id: 4, product_name: "nVidia GTX 1050 Ti 4GB GDDR5 VRAM", price: 13450, selected: false},
        {product_id: 5, product_name: "Intel i5 7200 kabylake CPU 3.6 GHz 4 cores 4 threads", price: 9800, selected: false},
        {product_id: 6, product_name: "AMD Ryzed 5 2600G CPU 3.2 GHz 4 cores 4 threads", price: 9380, selected: false},
        {product_id: 7, product_name: "8 GB Hyper-X DDR4 RAM memory 3200 MHz CL15", price: 3450, selected: false},
        {product_id: 8, product_name: "450W Sharkoon PSU 80 plus black semi modular", price: 2250, selected: false},
        {product_id: 9, product_name: "ATX Case w/ Acrilyc Glass panel & LED Strips", price: 1720, selected: false},
    ],
    sum: 0
}

(esto es solo una práctica, así que no estoy cargando los datos de una API de descanso o lo que sea)

Luego, me suscribo a la tienda redux con mi componente de la aplicación usando la función de conexión, y paso mis funciones mapStateToProps y mapDispatchToProps:

function mapStateToProps(state){
    return {
        products: state.products,
        sum: state.sum
    }
}

function mapDispatchToProps(dispatch){
    return {
        toggle: (product_id) => dispatch(ACTIONS.toggle(product_id))
    }
}


export default connect(mapStateToProps, mapDispatchToProps)(App)

Luego, dentro del componente de mi aplicación, creo una matriz constante a la que mapeo todos los productos y genero un retorno JSX de un div con contenido dentro de él, y en cada div agrego un linstener de eventos (onClick) que desencadena el this.props .toggle envío:

const products = this.props.products.map(product => {
    return (
        <div className="product" key={product.product_id} onClick={ () => {this.props.toggle(product.product_id) }}>
            <h2>{product.product_name}</h2>
            {product.selected ? ('') : (<h3>{product.price}</h3>)}
        </div>
    )
})

Y cuando se envía la acción, esto es lo que sucede en el reductor:

switch(action.type){
    case ACTION_TYPES.PRODUCT_TOGGLE:
        const newState = state
        newState.products[action.payload].selected = !newState.products[action.payload].selected
        if(newState.products[action.payload].selected === true){
            newState.sum = newState.sum + newState.products[action.payload].price
        } else {
            newState.sum = newState.sum - newState.products[action.payload].price
        }
        console.log(newState.sum)
        return newState
    default:
        return state
}

Si hago un registro de consola en el reductor, veo que se produce el cambio, pero los accesorios del componente contenedor no se actualizan.

2
  • ¿Está el const products = this......código en su rendermétodo o se ejecuta cuando renderse llama? Titus 22/06/19 a las 18:31
  • Se ejecuta cada vez que se llama al método de representación (o siempre que se actualiza el componente)SuperSimplePimpleDimple 22/06/19 a las 18:35
2

Está mutando el stateobjeto newStatey statees la misma referencia de objeto, por eso UIno se actualiza.

Tienes que devolver un nuevo objeto del reductor.

Crea un nuevo objeto antes de mutar el objeto como este

const newState = { ...state }
0
1

Cuando ejecuta newState = state, solo está creando una variable que es una referencia al mismo objeto que su estado anterior, por lo que a medida que asigna nuevos valores al objeto, está mutando el objeto anterior.

Redux y React-Redux usan controles estrictos de igualdad para determinar si su estado ha sido actualizado. Dado que las referencias de objeto son las mismas, piensa que el estado no ha cambiado.

const oldState = { a: 1 };
const newState = oldState;
newState.a = 2;
console.log(oldState);
console.log(newState);
console.log(oldState === newState);

Vea este artículo sobre el tema de la inmutabilidad: https://redux.js.org/faq/immutable-data#why-is-immutability-required-by-redux

0