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 鈥渃reateStore鈥 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 鈥榖asico鈥 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 { 鈥tate, 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