Reputation: 103
I have a little problem. I have diferent reducers in different files using a combine reducer, but when i try to use the "different" INITIAL STATES on these reducers it doesnt apear
For example
Product Reducer -> This is the state that i have to take
const INITIAL_STATE = {
productosInventario: [],
loading: false,
error: ''
Category Reducer -> this is the state for these reducer
const INITIAL_STATE = {
categorias: [],
categoriaActual: '',
loading: false,
error: ''
}
The idea is use both on these component:
Component:
import React, { Component } from 'react'
/* Components */
import { connect } from 'react-redux'
import { Link } from 'react-router-dom'
import CardItemInventario from '../components/inventario/CardItemInventario'
import * as ProductoActions from '../actions/ProductoActions'
import * as CategoriasActions from '../actions/CategoriasActions'
/* Styles */
import Spinner from '../components/Spinner'
import Fatal from '../components/Fatal'
import '../assets/styles/Containers/Inventario.scss'
class Inventario extends Component {
async componentDidMount() {
await this.props.traerTodosLosProductos();
}
handleChangeCategoria = (e) => {
this.props.cambioCategoriaInventario(e.target.value)
this.props.traerProductosPorCategoriaInventario(e.target.value)
}
/* Mapea todas las categorias disponibles en base de datos */
traerCategoriasInventario = () => this.props.categoriasInventario.map(category => {
let categori = category.categoria
return (
<option
value={categori}
>
{categori}
</option>
)
})
ponerContenido = () => {
if (this.props.loading) {
return (
<Spinner />
)
}
if (this.props.error) {
return (
<Fatal
error={this.props.error} />
)
}
return (
<>
<div className="button-add__cont">
<h1 className="button-add__title">
Inventario
</h1>
<Link to='/agregarinventario' className="button-add__cont--link">
Agregar a Inventario
</Link>
</div>
<select
name="categoriaSelect"
id=""
onChange={this.handleChangeCategoria}
className="selector-categoria"
>
<option value='' defaultValue> - Categoria -</option>
{this.traerCategoriasInventario()}
</select>
<div className="inventario-cont">
{this.imprimirProductos()}
</div>
</>
)
}
imprimirProductos = () => this.props.productosInventario.map(Productos =>
<CardItemInventario
nombre={Productos.nombre}
marca={Productos.marca}
cantidad={Productos.cantidad}
distribuidor={Productos.distribuidor}
precio={Productos.precio}
/>
)
render() {
console.log(this.props)
return (
<>
{this.ponerContenido()}
</>
)
}
}
const mapStateToProps = (reducers) => {
return (
reducers.ProductoReducer,
reducers.CategoriasReducer
)
}
const mapDispatchToProps = {
...ProductoActions,
...CategoriasActions
}
export default connect(mapStateToProps, mapDispatchToProps)(Inventario);
actions ->
productoActions:
import axios from 'axios'
import {
TRAER_TODOS_LOS_PRODUCTOS
} from '../types/ProductoTypes'
import { host_name, port_redux } from '../../../config'
import { CARGANDO, ERROR } from '../types/GlobalTypes'
const axiosConf = {
baseURL: `http://${host_name}:${port_redux}`
}
export const traerTodosLosProductos = () => async (dispatch) => {
dispatch({
type: CARGANDO
})
try {
const res = await axios.get(`/api/productos/get/listar`, axiosConf)
dispatch({
type: TRAER_TODOS_LOS_PRODUCTOS,
payload: res.data
})
} catch (error) {
console.log("Error: " + error)
dispatch({
type: ERROR,
payload: error.message
})
}
}
export const traerProductosPorCategoriaInventario = (categoria) => async (dispatch) => {
try {
const res = await axios.get(`/api/cotizacion/get/productosporcategoria/${categoria}`, axiosConf)
dispatch({
type: TRAER_TODOS_LOS_PRODUCTOS,
payload: res.data
})
} catch (error) {
console.log("Error: " + error)
dispatch({
type: ERROR,
payload: error.message
})
}
}
categoryActions_ >
import axios from 'axios'
import { host_name, port_redux } from '../../../config'
import { CARGANDO, ERROR } from '../types/GlobalTypes'
import {
LISTAR_CATEGORIAS,
CATEGORIA_ACTUAL
} from '../types/CategoriasTypes'
const axiosConf = {
baseURL: `http://${host_name}:${port_redux}`
}
export const traerCategoriasInventario = () => (dispatch) => {
const res = axios.get(`/api/categorias/get/listar`, axiosConf)
console.log(res)
dispatch({
type: LISTAR_CATEGORIAS,
payload: res.data.data
})
}
export const cambioCategoriaInventario = (categoria) => async (dispatch) => {
try {
dispatch({
type: CATEGORIA_ACTUAL,
payload: categoria
})
} catch (error) {
console.log("Error: " + error)
dispatch({
type: ERROR,
payload: error.message
})
}
}
Upvotes: 0
Views: 445
Reputation: 42160
const mapStateToProps = (reducers) => {
return (
reducers.ProductoReducer,
reducers.CategoriasReducer
)
}
It seems like you are having some confusion between state and reducer. The state is the object which contains all of your data. It is just a plain javascript object. The reducer is a function which takes the state object and an action and returns a new state object.
Your setup should look something like this:
const productoReducer = (state = INITIAL_PRODUCTOS, action ) => {
switch ( action.type ) {
case 'TRAER_TODOS_LOS_PRODUCTOS':
/* ... code here ... */
default:
return state;
}
}
const categoriasReducer = (state = INITIAL_CATEGORIAS, action ) => {
switch ( action.type ) {
case 'LISTAR_CATEGORIAS':
/* ... code here ... */
default:
return state;
}
}
export const reducer = combineReducers({
producto: productoReducer,
categorias: categoriasReducer,
})
Here we have two separate reducers for categories and for products, and each gets a separate initial state. We use combineReducers
to put them together so now the combined state has properties producto
and categorias
.
Your component Inventario
needs to access a bunch of values from state: categoriasInventario
, productosInventario
, loading
, and error
. Rather than passing the state into the component, we use mapStateToProps
to extract these values and pass them as props.
const mapStateToProps = (state) => {
return {
categoriasInventario: state.categorias.categorias,
productosInventario: state.productos.productosInventario,
loading: state.categorias.loading || state.productos.loading,
error: state.categorias.error || state.productos.error,
}
}
Upvotes: 1