No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Compra acceso a todo Platzi por 1 año

Antes: $249

Currency
$209/año

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

14D
5H
3M
12S

Integrando Redux

8/22
Recursos

Aportes 21

Preguntas 5

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

o inicia sesión.

Buen aporte ese de que ahora Redux recomienda Redux toolkit por encima del. La verdad ni sabia.

Según su documentación se debe a que Redux toolkit simplifica el proceso, tiene mejores practicas y elimina codigo repetitivo.

Pero no encontre que fuera por cuestiones de rendimiento y que planean dejar el “createStore” API en la libreria.

Por eso me alivia que la profesora comento que ya lo íbamos a ver más adelante en el curso (aun no he llegado ahi), de esa manera estaremos actualizados.

  • mapStateToProps es una función recibe nuestro estado y retorna un objeto cuyas propiedades van a ser enviadas a las props del componente que se está conectado a redux.
  • mapDispatchToProps es una función que recibe el dispatcher de redux y retorna un objeto que será mapedo a las propiedades con los action creatrors

No entendi nada

Aqui les dejo mi codigo utilizando utilizando typescript y vite.
Estoy aplicando lo aprendido en otros cursos, si ven algo a mejorar comenten

// main.tsx
import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import { pokemonReducer  } from "./reducers/pokemon";
import { Provider } from "react-redux";
import { legacy_createStore as createStore } from 'redux'
// import './index.css' 

const store = createStore(pokemonReducer);

ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <Provider store={store} >
      <React.StrictMode>
        <App />
      </React.StrictMode>
  </Provider>

)

// App.tsx
import { useEffect, useState } from 'react'
import { connect } from 'react-redux'
import { Col } from 'antd'
import { Search } from './components/Search'
import { PokemonList } from './components/PokemonList'
import { getPokemons, PokemonType } from './api'
import logo from './statics/logo.svg'
import './App.css'
import { setPokemmons as setPokemmonsActions } from './actions'

type AppType = {
  pokemons:PokemonType[], setPokemons:any
}

function App({pokemons, setPokemons}: AppType ) {
  // const [pokemons,setPokemons] = useState<PokemonType[]>([]);
  useEffect(()=>{
    async function fetchPokemon(){
        const pkmns = await getPokemons();
        setPokemons(pkmns as PokemonType[])
    } 
    fetchPokemon();
  },[])
  return (
    <div className="App">
      <Col span={4} offset={10}>
        <img src={logo} alt="Pokedux" />
      </Col>
      <Col span={8} offset={8}>
        <Search />
      </Col>
      <PokemonList pokemons={pokemons} />
    </div>
  )
}

const mapStateToProps = (state:any)=>({
  pokemons: state.pokemons
})

const mapDispatchToProps = (dispath:any)=>({
  setPokemons: (value:PokemonType[])=> dispath(setPokemmonsActions(value))
})

export default connect(mapStateToProps, mapDispatchToProps)(App)

// reducers/pokemon.ts
import { SET_POKEMONS } from "../actions/types"
import { PokemonType } from "../api"

type TypeState = {
    pokemons: PokemonType[]
}

const initialState: TypeState = {
    pokemons: []
}

export const pokemonReducer = (state:TypeState = initialState, action:any)=>{
    switch(action.type){
        case SET_POKEMONS:
            return {...state, pokemons: action.payload}

        default:
            return state
    }

}
// actions/index.ts
import { PokemonType } from "../api";
import { SET_POKEMONS } from "./types";


export const setPokemmons = (payload: PokemonType[])=>({
    type: SET_POKEMONS,
    payload
})

te amo redux xd

Como estoy haciendo este curso directamente se me esta complicando entender todo ya que no quise hacer el curso ‘basico’ de redux, por que esta muy desactualizado sea el de react router 5 y redux o el de redux por bedu

Mi practica

main.jsx

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App'
import {pokemonsReducer} from "./reducers/pokemons";
import {Provider} from "react-redux";
import {legacy_createStore as createStore} from "redux";
import './index.css'

const store = createStore(pokemonsReducer);

ReactDOM.createRoot(document.getElementById('root')).render(
    <React.StrictMode>
        <Provider store={store}>
            <App/>
        </Provider>
    </React.StrictMode>
)

App.jsx

import {Col} from 'antd';
import Searcher from "./components/Searcher";
import {useEffect} from 'react'
import {connect} from 'react-redux'
import PokemonList from "./components/PokemonList.jsx";
import {getPokemon} from "./api";
import {setPokemons as setPokemonsActions} from "./actions/index.js";
import Logo from "./assets/logo.svg";
import './App.css'

function App({pokemons, setPokemons}) {
    useEffect(() => {
        const fetchPokemons = async () => {
            const response = await getPokemon();
            setPokemons(response);
        }
        fetchPokemons();
    }, [])
    return (
        <div className="App">
            <Col span={4} offset={10}>
                <img src={Logo} alt="pokeapi"/>
            </Col>
            <Col span={8} offset={8}>
                <Searcher/>
            </Col>
            <PokemonList pokemons={pokemons}/>
        </div>
    )
}

const mapStateToProps = (state) => ({
    pokemons: state.pokemons
});
const mapDispatchToProps = (dispatch) => ({
    setPokemons: (value) => dispatch(setPokemonsActions(value))
})
export default connect(mapStateToProps,mapDispatchToProps)(App)

reducers/pokemons.js

import {SET_POKEMON} from "../actions/types.js";

const initialState = {pokemons: []};

export const pokemonsReducer = (state, action) => {
    switch (action.type) {
        case SET_POKEMON:
            return {...state, pokemons: action.payload}
            break;
        default:
            return {...state};
            break;
    }
}

action/index.js

import {SET_POKEMON} from "./types";

export const setPokemons = (payload) => ({
    type: SET_POKEMON,
    payload
});

action/types.js

export const SET_POKEMON = 'SET_POKEMON';
npm install redux react-redux 

Primera Forma de Conectar Redux Con React

Le agrege un loading skeleton, utilizando el estado y la librería de estilos que la profe
nos proporcionó al inicio del curso.
Espero les Sirva a alguien y agredeceria el Feedback.
Primero Se crean los Actions Types

const SET_POKEMONS= 'SET_POKEMONS';
const SET_ERROR= 'SET_ERROR';
export {SET_POKEMONS,SET_ERROR}

despues los Dispatch o actualizadores del estado

import { SET_ERROR, SET_POKEMONS } from "./types";

export const setError = (payload) => {
  return {
    type: SET_ERROR,
    payload,
  };
};
export const setPokemons = (payload) => ({
  type: SET_POKEMONS,
  payload,
});

Pasamos a crear el reducer con un estado inicial

import { SET_ERROR, SET_POKEMONS } from "../actions/types";

const initialState = {
  pokemons: [],
  loading:true,
  error:false
};
export const pokemonsReducer = (state = initialState, action) => {
  switch (action.type) {
    case SET_POKEMONS:
      return {
        ...state,
        pokemons: action.payload,
        loading:false,
      };
    case SET_ERROR: 
    return {
        ...state,
        error:true
    }
    default:
      return state;
  }
};

en el lugar que vallamos a utilizar el estado creamos las funciones para que se conecten a las props de nuestro componente

import { Searched } from './components/Searched';
import { connect} from 'react-redux'
import {Col, Row} from 'antd'
import './App.css'
import { setError, setPokemons as setPokemosActions } from './actions';
import { PokemonList } from './components/PokemonList';
import { PokeSkeleton } from './components/PokeSkeleton';
import { useEffect } from 'react';
import { getPokemons } from './services/PokeApi';

function App({setError,loading,setPokemons,pokemons,error}) {
  useEffect(()=>{
    getPokemons().then(res=>setPokemons(res.results)).catch(err=>setError(error))
  },[])
  return (
    <div className="app">
      <Col span={4} offset={10} style={{marginBottom:30}}>
        <img src='https://static.platzi.com/media/tmp/class-files/github/curso-redux/curso-redux-01-pokeapi/src/statics/logo.svg' alt='pokedux'/>
      </Col>
      <Col span={8} offset={8} >
        <Searched/>
      </Col>
      <Row style={{marginTop: 50 }} justify={'center'} gutter={20}> 
        { loading ? <PokeSkeleton/>:<PokemonList pokemons={pokemons}/>}
      </Row>
    </div>
  )
}
// mapea el stado del redux y para pasarlo a las props
const mapStateToProps=state =>(
 {
  pokemons:state.pokemons,
  loading:state.loading,
  error:state.error
 }
);
//mapea los activadores del estado para pasarlos a las props y asi consumirlos en 
//nuestro componente
const mapDispatchToProps= dispatch=> ({
  setPokemons:(value)=> dispatch(setPokemosActions(value)),
  setError:(value)=>dispatch(setError(value))
});

//utilizamos la functtion connect de react-redux para conectar los dispatch y el estado con las props del componente
export default connect(mapStateToProps,mapDispatchToProps)(App);

y Por último en el índex de nuestra APP, envolvemos toda nuestra app con un provider que contenga todo el store.

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import { pokemonsReducer } from "./reducers/pokemons";
import { Provider } from "react-redux";
import { legacy_createStore as createStore } from "redux";

// le pasamos nuestro reducer al store
const store = createStore(pokemonsReducer);

ReactDOM.createRoot(document.getElementById("root")).render(
  <Provider store={store}>
    <React.StrictMode>
      <App />
    </React.StrictMode>
  </Provider>
);

Parece complicado al principio por todas las acciones que hay que hacer en el flujo del codigo, pero creo que a la larga se aprende todo.

¿Quien le pasa las props al componente APP?
Por si a alguien le surgio tambien esta duda, pues resulta que la funcion connect es quien provee de pokemons y setPokemons al componente APP

No puede explicarse tan mal esta clase. Se estan tomando por sabidos muchos conceptos que en ningun lado explican

Es menos complicado configurarlo de esta manera.

import React from 'react'
import { Todo } from './components/Todo'

import { Provider } from 'react-redux' 
import { store } from './Redux/store'

const App = () => {
  return (
    <Provider store={ store }>
      <Todo />
    </Provider>
  )
}

export default App
Creo que este guión lo deberían refactorizar; sinceramente no se entiende la mayor parte de lo que hace en los primeros 5 minutos
Un poco de documentación util para los primeros 5 minutos: <https://redux.js.org/usage/usage-with-typescript#typing-the-connect-higher-order-component> Así es como lo explica Redux, me pareció más entendible

Yo lo tuve que conectar de esta manera.

const mapStateToProps = (state) => ({
  pokemons: state.pokemons
})

const mapDispatchToProps = (dispatch) => ({
  setPokemons: (value) => dispatch(setPokemonsActions(value))
})

const ConnectedApp = connect(mapStateToProps, mapDispatchToProps) (App)
export default ConnectedApp;

En mi caso preferí tener parte de la lógica en un sólo lugar y utilicé un objeto reductor en vez del switch por tema de legibilidad una vez crezca la cantidad de estados que agreguemos.

//Estado inicial
const initialState = {
    pokemons : [],
}
//Tipos de acciones
const actionType = {
    setPokemons : "Set Pokemons",
}
//Objeto reductor
const objectReducer = (state, payload) => ({
    [actionType.setPokemons] : {
        ...state,
        pokemons: payload,
    }
})
//Función reductora la cual devuelve el estado actualizado
function pokemonsReducer(state = initialState, action){
    return objectReducer(state, action.payload)[action.type] || state;
}
//Acciones creadoras
const handleSetPokemons = (payload)=>(
    {
        type :actionType.setPokemons,
        payload,
    }
)

export {pokemonsReducer, handleSetPokemons}

El resto está igual a como fue realizado en la clase.

Asi hice el if en lugar del switch en el archivo de reducers

if(action.type === SET_DATA){
return { …state, data: action.payload };
}
return state;

No se si mas adelante en el curso se cambiara la manera de conectar App con redux, pero aqui dejo mi codigo usando los hooks useDispatch y useSelector en vez de usar connect, mapStateToProps y mapDispatchToProps

import { useEffect } from 'react';
import { Col } from 'antd';
import Searcher from './Components/Searcher';
import PokeList from './Components/PokeList';
import { getPoekmon } from './api';
import { useDispatch, useSelector } from 'react-redux';

import logo from './statics/logo.svg';

import './App.css';
import { setPokemons } from './actions';

function App() {
  const dispatch = useDispatch();
  const pokemons = useSelector((state) => state?.pokemons);

  useEffect(() => {
    const fetchPokemons = async () => {
      const results = await getPoekmon();
      dispatch(setPokemons(results));
    };
    fetchPokemons();
  }, []);
  return (
    <div className='App'>
      <Col span={4} offset={10}>
        <img className='logo' src={logo} alt='Pokedux' />
      </Col>
      <Col span={8} offset={8}>
        <Searcher />
      </Col>
      <PokeList pokemons={pokemons} />
    </div>
  );
}

export default App;

En la vieja escuela ese legacy era el día a día, el flujo era claro, pero los hooks y toolkit definitivamente facilitan la vida

createStore por legacy_createStore antes de usar el nuevo ToolKit

jaja me da mucha risa como la profesora hace gestos y mueve su cuerpo xd k crack