No tienes acceso a esta clase

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

Integrando Redux

8/22
Recursos

Aportes 31

Preguntas 5

Ordenar por:

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

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

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>
);

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

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';
Sin dudas es la peor clase que he visto en platzi, solo superada por el curso de dart que había antes que estaba completamente desactualizado y solo era un profesor leyendo diapositivas. Aqui la profesora parece que solo pega comandos y lineas de codigo sin explicar a profundidad las cosas y la verdad es frustrante porque se supone que tienes platzi para que te expliquen bien, no para que te den mil vueltas y las explicaciones estén muy por encima. Deberian actualizar este curso
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

¿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

npm install redux react-redux 
Creo que el curso esta un poco desactualizado, además sinceramente creo que no se explica detenidamente los conceptos que se utilizan, necesitan mejorar esta parte muchísimo

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.

Hay cosas que vienen del anterior curso, pero igual me perdi con esta explicacion, voy a tener que ver esta clase mas de 2 veces.

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.

drop este curso esta muy desactualizado

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
Muy enredada esta clase
Para integrar Redux en un proyecto, sigue estos pasos: 1. Instala las librerías necesarias: `npm install redux react-redux`. 2. Crea una carpeta llamada `Actions` y define los tipos de acciones en un archivo de constantes. 3. Implementa un `Action Creator` que retorne un objeto con el tipo de acción y el `payload`. 4. En `app.js`, utiliza `connect` para conectar tu componente a Redux. - Define `mapStateToProps` para seleccionar el estado que necesitas. - Define `mapDispatchToProps` para mapear los creadores de acciones a los props del componente. 5. Crea un `reducer` en la carpeta `reducers` que maneje el estado y las acciones. 6. En `index.js`, importa el `reducer`, el `Provider` y crea el `store`. 7. Envuelve tu aplicación con el `Provider` pasando el `store`. 8. Reemplaza el manejo de estado local con props de Redux en tus componentes. Estos pasos te permitirán integrar Redux de manera efectiva en tu aplicación.
Buenas. Por aqui dejo mi aporte. Por lo que estuve viendo e investigando, ya en redux no se utiliza la función legacy\_createStore ni la de createStore; ahora se utiliza la función configureStore del paquete @reduxjs/toolkit. Anexo código de ejemplo: ```js import React from 'react'; import ReactDOM from 'react-dom/client'; import { Provider } from 'react-redux'; import { configureStore } from '@reduxjs/toolkit'; import { pokemonsReducer } from './reducers/pokemons'; import App from './App'; import './index.css'; const root = ReactDOM.createRoot(document.getElementById('root')); const store = configureStore({ reducer: pokemonsReducer }) root.render( <React.StrictMode> <Provider store={store}> <App /> </Provider> </React.StrictMode> ); ```
Definitivamente la PEOR clase que he visto en un curso de Platzi hasta ahora.

Les paso el codigo con la explicación de como se esta implementando redux en esta primera forma:

  • Una vez definido los primeros pasos (actionTypes, actions, reducers), pasamos a usar el metodo connect del paquete react-redux, y creamos las funciones de customizacion de estado y disptacher
  //App.js
    
    import { useEffect } from 'react';
    import './App.css';
    import { connect } from 'react-redux';
    import { Col } from 'antd';
    import Searcher from './components/Searcher';
    import PokemonList from './components/PokemonList';
    import logo from './statics/logo.svg'
    import { getPokemons } from './api';
    import { setPokemons as setPokemonsActions } from './actions';
    
    //recibimos los nombre personalizados del estado y del dispatcher
    function App({ pokemons, setPokemons}) {
      //const [pokemons, setPokemons] = useState([])
      console.log(pokemons)
      useEffect(() => {
        const fetchPokemons = async () => {
          const pokemonRes = await getPokemons();
          setPokemons(pokemonRes);
    
        }
        fetchPokemons();  
      },[])
      return (
        <div className="App">
          <Col span={4} offset={10}>
            <img src={logo} alt="" />
          </Col>
          <Col span={8} offset={8}>
            <Searcher />
          </Col>
          {/* <PokemonCard /> */}
          <PokemonList pokemons={pokemons}/>
        </div>
      );
    }
    
    // esta funcion personaliza el nombre del estado especifico que vamos a usar del estore
    const mapStateToProps = (**state**) => {
      return {
        pokemons: **state**.pokemons
      }
    }
    
    // esta funcion personaliza el nombre del dispatcher, que es como el setState
    const mapDispatchToProps = (**dispatch**) => {
      return {
    
    	// el value es el valor o payload de lo que vamos a actualizar en nuestro estado
    	// 'setPokemonAction' es la accion especifica que contiene la sintaxis que la sintaxis de dispatch puede recibir
    	// es como si dijera: 
      // setPokemons: *(value) => **dispatch**((value) => ({ type: SET_POKEMONS, value }))*
        setPokemons: (value) => **dispatch**(setPokemonsActions(value))
      }
    }
    
    // Usamos el metodo connect para personalizar nuestro estado y dispatcher que obtendremos del provider que envolvera a este componenyte app
    export default connect(mapStateToProps, mapDispatchToProps)(App);
  • Usamos el provider de react-redux para obtener el contexto (estado y dispatcher del store) de redux a nuestros componentes, creamos el store con el metodo ‘legacy_createStore’ y le pasamos el reducer que hemos creado
  import React from 'react';
    import ReactDOM from 'react-dom/client';
    import './index.css';
    import App from './App';
    import { Provider } from 'react-redux'
    import { **legacy_createStore** as createStore } from 'redux'
    import { pokemonReducer } from './reducers/pokemons';
    
    const root = ReactDOM.createRoot(document.getElementById('root'));
    const store = createStore(pokemonReducer)
    
    root.render(
      <React.StrictMode>
    		{/*Asignamos el store al provider*/}
        <Provider store={store}>
          <App />
        </Provider>
      </React.StrictMode>
    );
porque tantos archivos index.js me marea...
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;

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