Platzi
Platzi

LA EDUCACI脫N ES UN REGALO 隆ACCEDE AL PRECIO ESPECIAL!

Antes: $249
$149
Currency
Antes: $249
Ahorras: $100
COMIENZA AHORA
Termina en: 16D : 16H : 25M : 15S

隆Bienvenida! Este es un curso especial de React Hooks

1

驴Qu茅 aprender谩s en el Curso Profesional de React Hooks?

2

驴Qu茅 son los React Hooks y c贸mo cambian el desarrollo con React?

Introducci贸n a React Hooks

3

useState: estado en componentes creados como funciones

4

useEffect: olvida el ciclo de vida, ahora piensa en efectos

5

useContext: la fusi贸n de React Hooks y React Context

6

useReducer: como useState, pero m谩s escalable

7

驴Qu茅 es memoization? T茅cnicas de optimizaci贸n en programaci贸n funcional

8

useMemo: evita c谩lculos innecesarios en componentes

9

useRef: manejo profesional de inputs y formularios

10

useCallback: evita c谩lculos innecesarios en funciones

11

Optimizaci贸n de componentes en React con React.memo

12

Custom hooks: abstracci贸n en la l贸gica de tus componentes

13

Third Party Custom Hooks de Redux y React Router

Configura un entorno de desarrollo profesional

14

Proyecto: an谩lisis y retos de Platzi Conf Store

15

Instalaci贸n de Webpack y Babel: presets, plugins y loaders

16

Configuraci贸n de Webpack 5 y webpack-dev-server

17

Configuraci贸n de Webpack 5 con loaders y estilos

18

Loaders de Webpack para Preprocesadores CSS

19

Flujo de desarrollo seguro y consistente con ESLint y Prettier

20

Git Hooks con Husky

Estructura y creaci贸n de componentes para Platzi Conf Store

21

Arquitectura de vistas y componentes con React Router DOM

22

Maquetaci贸n y estilos del home

23

Maquetaci贸n y estilos de la lista de productos

24

Maquetaci贸n y estilos del formulario de checkout

25

Maquetaci贸n y estilos de la informaci贸n del usuario

26

Maquetaci贸n y estilos del flujo de pago

27

Integraci贸n de 铆conos y conexi贸n con React Router

Integraci贸n de React Hooks en Platzi Conf Merch

28

Creando nuestro primer custom hook

29

Implementando useContext en Platzi Conf Merch

30

useContext en la p谩gina de checkout

31

useRef en la p谩gina de checkout

32

Integrando third party custom hooks en Platzi Conf Merch

Configura mapas y pagos con PayPal y Google Maps

33

Paso a paso para conectar tu aplicaci贸n con la API de PayPal

34

Integraci贸n de pagos con la API de PayPal

35

Completando la integraci贸n de pagos con la API de PayPal

36

Paso a paso para conectar tu aplicaci贸n con la API de Google Maps

37

Integraci贸n de Google Maps en el mapa de checkout

38

Creando un Custom Hook para Google Maps

Estrategias de deployment profesional

39

Continuous integration y continuous delivery con GitHub Actions

40

Compra del dominio y despliega con Cloudflare

Optimizaci贸n de aplicaciones web con React

41

Integraci贸n de React Helmet para mejorar el SEO con meta etiquetas

42

An谩lisis de performance con Google Lighthouse

43

Convierte tu aplicaci贸n de React en PWA

Bonus: trabaja con Strapi CMS para crear tu propia API

44

Crea una API con Strapi CMS y cons煤mela con React.js

驴Qu茅 sigue en tu carrera profesional?

45

Pr贸ximos pasos para especializarte en frontend

Crea una cuenta o inicia sesi贸n

隆Contin煤a aprendiendo sin ning煤n costo! 脷nete y comienza a potenciar tu carrera

useContext: la fusi贸n de React Hooks y React Context

5/45
Recursos

Aportes 46

Preguntas 8

Ordenar por:

Los aportes, preguntas y respuestas son vitales para aprender en comunidad. Reg铆strate o inicia sesi贸n para participar.

A mi me gusta trabajar los context de la siguiente manera:

Ya luego el index.js queda solo:

Y para modificarlo ser铆a (estoy usando tailwindcss por lo que solo pondr茅 la l贸gica ac谩):

Al tener un bot贸n con el handleClick, cambiar谩 el valor del theme (valor del context), cambiando as铆 las clases. Para los componentes que no tengan action pero que si cambien clases, solo se destructura { theme } = useContext(ThemeContext)

馃毃 IMPORTANTE: La llegada de React Hooks y la actualizaci贸n de React Context NO reemplazan Redux.
馃憠 Redux NO est谩 muerto, pero t煤 no lo sabes usar: 隆Larga vida a Redux!


No es mucho pero es trabajo honesto, usando 鈥榰seContext鈥

En la parte de a帽adir el color, Oscar no uso {color: color} porque en javascript podemos simplificarlo siempre y cuando el key del object se llame igual a la variable que ser谩 su valor.
.

const color = 'red'

const obj = { color }

.
SI fuera el nombre de la variable distinta ser铆a as铆:

const color2 = 'red'

const obj = { color: color2 }

Yo hice un modo obscuro, que detecta el modo de tu sistema operativo, y lo adapta, recuerda el modo en que dejaste la web la ultima vez que la visitas y obviamente un bot贸n.

Aun es basico, por que me falta mandar el tema seleccionado a los componentes.

Manden feedback

Header.jsx queda asi

import React from "react";

const Header = () => {
  return (
    <div className="Header">
      <h1>ReactHooks</h1>
    </div>
  );
};

export default Header;

ThemeContext.js asi

import React from "react";

export const themes = {
  dark: {
    color: "#4ecca3",
    background: "#232931",
  },
  light: {
    color: "#1e56a0",
    background: "#f5feff",
  },
};

const ThemeContext = React.createContext(themes.dark);

export default ThemeContext;

index.js quit茅 todo

y App.js queda asi

import React, { useState, useEffect } from "react";
import "./App.css";
import Header from "./components/Header";
import Caharacters from "./components/Characters";
import ThemeContext, { themes } from "./context/ThemeContext";

function App() {
  useEffect(() => {
    if (localStorage.getItem("theme") === "dark") {
      darkTheme();
    } else if (localStorage.getItem("theme") === "light") {
      lightTheme();
    } else if (localStorage.getItem("theme") === null) {
      detectColorScheme();
    }
  });

  const [theme, setTheme] = useState(themes.dark);

  const darkTheme = () => {
    setTheme(themes.dark);
    document.documentElement.setAttribute("data-theme", "dark");
    localStorage.setItem("theme", "dark");
  };

  const lightTheme = () => {
    setTheme(themes.light);
    document.documentElement.setAttribute("data-theme", "light");
    localStorage.setItem("theme", "light");
  };

  const detectColorScheme = () => {
    if (window.matchMedia("(prefers-color-scheme: dark)").matches) {
      darkTheme();
    } else if (window.matchMedia("(prefers-color-scheme: light)").matches) {
      lightTheme();
    } else {
      darkTheme();
    }
  };

  const handleClick = () => {
    if (theme === themes.light) {
      darkTheme();
    } else if (theme === themes.dark) {
      lightTheme();
    }
    //theme === themes.dark ? setTheme(themes.light) : setTheme(themes.dark);
  };

  return (
    <ThemeContext.Provider value={theme}>
      <div style={theme} className="App">
        <Header />
        <button type="button" onClick={handleClick}>
          Change Color Theme
        </button>
        <Caharacters />
      </div>
    </ThemeContext.Provider>
  );
}

export default App;

Esta forma ya lo hab铆a echo con javascript canilla, ahora quiero adaptarlo totalmente a React 馃挭馃徎鈿

Hola aqui coloco mi solucion y el paso a paso del porque

  1. debido a que aprendimos useContext ahroa podemos compartir informacion entre componentes, La informacion que vamos a compartir en este caso sera el estado que creamos anteriormente, esdecir quitamos el estado darkMode del componente Header y lo ponemos en App. cabe aclarar que los componentes que esten encerrados en <ThemeContext.Provider> son los unicos que veran el estado que se compartira, debido a eso puse <ThemeContext.Provider> en app.js, para que se pueda compartir entre el componente App y Header
import './App.css';
import Header from './components/Header';
import Characters from './components/Characters';
import ThemeContext from './context/ThemeContext';
import React, { useState, useContext } from 'react'



function App() {

  
  const [darkMode, setDarkMode] = useState(false)

  return (
    <ThemeContext.Provider value={{darkMode, setDarkMode}}>
      <div className={darkMode? "Dark": "Light"}>
        <h1>hola pescado</h1>
        <Header></Header>
        <Characters></Characters>
      </div>
    </ThemeContext.Provider>
  );
}

export default App;

  1. ahora que el componente app y header pueden observar el estado, y anteriormente ya habiamos programado que el cambio de estado lo hiciera Header al dar clic. entonces no debemos cambiar nada en este componente, solo debemos poner el hook useContext para poder manipular el estado desde aqui y quitar el estado declarado, ya que lo pusimos en App.js
import React, { useState, useContext } from 'react'
import ThemeContext from '../context/ThemeContext';

export default function Header() {
    
    const {darkMode, setDarkMode} = useContext(ThemeContext);
    const handleClick = () => {
        setDarkMode(!darkMode);
    }

    return (
        <div className="Header" >
            <h1 >React Hooks</h1>
            <button type="button" onClick={handleClick}>{darkMode ? 'Dark Mode' : 'Light Mode'}</button>

        </div>
    )
}

3)La manera en la que cambie el background fue con un condicional al momento de nombrar la clase: si darkMode es true entonces llama a la clase Light y si darkMode es false llama a la clase Dark, estas clases se crearon en app.css

<div className={darkMode? "Light": "Dark"}>
.Dark{
  background-color: darkblue;
}

.Light{
  background-color: white;
}

Apuntes

  • Conecta todos tus componentes de una manera f谩cil con React
  • Nos ayuda pasar la informaci贸n entre componentes
  • Conectar sin necesidad de pasar props y no estar ligados a pasar la informaci贸n de padre a hijo

Ejemplo

import React from 'react'

const ThemeContext = React.createContext(null);
// Nos Devuelve un Provider que luego lo podemos
// usar para envolver nuestra aplicaci贸n

export default ThemeContext;

Usando el Provider:

import React from 'react';
import ReactDOM from 'react-dom';
import ThemeContext from './context/ThemeContext';

ReactDOM.render(
  <React.StrictMode>
    <ThemeContext.Provider value="blue">
      {/*Mi Aplicaci贸n*/}
    </ThemeContext.Provider>
  </React.StrictMode>,
  document.getElementById('root')
);
  • Este formato nos permite tener toda una l贸gica establecida con configuraciones que podemos transmitir a nuestra aplicaci贸n
  • Se podr铆a usar para tener todo un estado y compartirlo por todos los lugares seg煤n sea el caso y activarlo seg煤n el componente que nosotros necesitemos
    • Debido a que estamos pasando el valor en nuestro Provider
    • Logrando que nuestro contexto use esta informaci贸n para recibir esta informaci贸n y poderlo presentar a lo largo de nuestra aplicaci贸n

Dos sugerencias al momento que uses useContext

  1. Un error muy comun es hacerlo globalmente disponible para todos tus componentes de tu aplicacion, cuando realmente solo es necesario para una parte de tu aplicacion. Tener el value del contexto en scope en el area donde solo se necesita va a mejorar el performance y el mantenimiento.

  2. Que pasaria si alguien consume tu context value sin usar el Context Provider? El error que te muestra React, no ayuda mucho. Por eso siempre es bueno validar si existe el context, y tambien crear un custom hook del Context que uses, en este caso seria algo asi:

function useTheme() {
  const context = React.useContext(ThemeContext)
  if (!context) {
    throw new Error('useCount must be used within a CountProvider')
  }
  return context
}

Y este custom hook lo usas en los componentes donde necesites ese Theme Context.

Para el Profesor es sencillo de entender, sin embargo yo debo hacer un 茅nfasis para qui茅n no lo entendi贸i a la primera, me pas贸 a m铆:

  • Objetivo: Se debe crear un Contexto del cu谩l se van a traer datos, o la informaci贸n del contexto, para que alg煤n componente lo consuma.

    En lenguaje m谩s humano, imagina que es un restaurante m贸vil que puedes conectar a la ventana de tu casa para que te prepare y entregue lo que ah铆 dentro se puede pedir, consultar, consumir.
    .
  • 1 - Se debe crear un Contexto de d贸nde poder obtener esa informaci贸n.

/// ThemeContext.js

import React from 'react'

const ThemeContext = React.createContext(null);

export default ThemeContext;
  • 2 - Definir la ubicaci贸n del Provider para que todo el App pueda acceder a la informaci贸n sin importar el nivel.
  • 3 - 鈥楧efinir la carta del restaurante鈥: Definir la data que va a entregar el Provider dentro del contexto.
    /// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import ThemeContext from './context/ThemeContext';

const COLOR_MODE = {
  darkColorMode: 'dark-mode',
  lightColorMode: 'light-mode',
};

ReactDOM.render(
  <React.StrictMode>
    <ThemeContext.Provider value={COLOR_MODE}>
      <App />
    </ThemeContext.Provider>
  </React.StrictMode>,
  document.getElementById('root')
);

El par谩metro value es en donde vamos a colocar la informaci贸n que ser谩 consumida.

  • Existe un Provider y un Consumer . Estos dos van a entregar y consumir, respectivamente, la informaci贸n que habita en el contexto, dependiendo de la necesidad.
    Nota: Se recomienda que el Provider sea el componente de m谩s alto nivel dentro del App.
    .
  • 4 - Conectar la informaci贸n del Provider (contexto) con el componente.
  • 5 - Consumir.
///  App.js
import React, { useContext, useState } from 'react';
import Header from './components/Header';
import Characters from './components/Characters';
import ThemeContext from './context/ThemeContext';
import './App.css';

function App() {
  const [darkMode, setDarkMode] = useState(false);
  const {darkColorMode, lightColorMode} = useContext(ThemeContext);
  
  const handleClick = () => {
    setDarkMode(!darkMode);
  }
    
  return (
    <div className={`App ${darkMode ? darkColorMode : lightColorMode}`}>
      
      <Header />

      <div>
        <button type="button" onClick={handleClick}>
          { darkMode ? 'Change to LightMode' : 'Change to DarkMode' }
        </button>
      </div>

      <Characters />

    </div>
  );
}

export default App;
///  Header.js
import React, {useContext} from 'react'
import ThemeContext from '../context/ThemeContext'

const Header = () => {
    const {titleColor} = useContext(ThemeContext);
    console.log(titleColor)
    
    return (
        <div className="Header">
            <h1 >React Hooks</h1>
        </div>
    )
}

export default Header

Espero los pueda ayudar!

![](

En mi caso, yo acostumbro a exportar de una vez el useContext en el archivo donde se crea el contexto. Quedar铆a algo as铆:

import { createContext, useContext } from 'react';

export const ThemeContext = createContext(null);

export function useTheme() {
  return useContext(ThemeContext);
}

Posteriormente, en el componente, solo debo importar useTheme y usarlo directamente:

import React,{useState} from 'react';
import {useTheme} from 'context/theme'

const Header = () => {
    const [darkMode,setDarkMode] = useState(false)
    const color=useTheme()
	.........

Les dejo el link de mi repositorio, hecho en Nextjs:
https://github.com/danyel117/platzi-conf-store

Mi proyecto hasta ahora:

No puedo usar un useState en un provider?, me esta tirando error por eso pregunto

Yo creo que la carpeta context m谩s bien deber铆a llamarse provider/s y tu ThemeContext -> ThemeProvider para as铆 exportarlo como un componente (provider) que recibe hijos, de esta manera el c贸digo queda m谩s claro y limpio

<h3>Otra forma de usar useContext</h3>

En lo personal me gusta usar useContext de la siguiente manera

Context.js

import React, { createContext } from "react";

const ThemeContext = createContext();

export const ContextProvider = ({ children }) => {
  // Aca defines toda tu logica.

  const color = "red";

  return (
    <ThemeContext.Provider value={{ color }}>{children}</ThemeContext.Provider>
  );
};

export default ThemeContext;

index.js

import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import App from "./App";
import { ContextProvider } from "./Context";

ReactDOM.render(
  <React.StrictMode>
    <ContextProvider>
      <App />
    </ContextProvider>
  </React.StrictMode>,
  document.

Luego para acceder alguna propiedad que hayas definido en tu context solo tienes que hacer:

import React, { useContext } from "react";
import "./App.css";
import ThemeContext from "./Context";

function App() {
  const { color } = useContext(ThemeContext);

  return (
    <div>
      <h1 style={{ color }}>Hola mundo</h1>
    </div>
  );
}

export default App;

Context

import React, { useState } from 'react';

const initialState = 'light';

const ThemeContexProvider = ({ children }) => {
  const [theme, setTheme] = useState(initialState);
  return <ThemeContext.Provider value={{ theme, setTheme }}>{children}</ThemeContext.Provider>;
};

export default ThemeContexProvider;
export const ThemeContext = React.createContext(initialState);

Header

import React, { useContext } from 'react';

import { ThemeContext } from '../context/ThemeContext';

const Header = () => {
  const { theme, setTheme } = useContext(ThemeContext);

  return (
    <div className={`flex flex-col items-center pb-5 md:pb-3 bg-${theme}-100 text-${theme}-200`}>
      <h1 className="text-5xl font-bold py-4">React Hooks!!!</h1>
      <div className="flex flex-row">
        <button
          className="focus:outline-none border-2 border-gray-900 rounded-md px-4 py-2 mr-2 bg-gray-800 text-gray-50"
          onClick={() => setTheme('dark')}
        >
          Dark Mode
        </button>
        <button
          className="focus:outline-none border-2 border-gray-900 rounded-md px-4 py-2 bg-gray-300 text-gray-900"
          onClick={() => setTheme('light')}
        >
          Light Mode
        </button>
      </div>
    </div>
  );
};

export default Header;```

Usando el ejemplo de Antonio Jos茅 Hern谩ndez Medina, que esta muy interensante, combinado con la idea de Oscar Barajas, me ha quedado un experimiento donde uso el contexto para cambiar el borde de color y el levantamiento de estado y los estados para el modo luz o oscuro

Si tambi茅n quedaste con la duda de porqu茅 se usa la palabra Context.Provider les dejo una lectura que me lo aclar贸 much铆simo.
Creo que tambi茅n es importante complementar para saber que esta funcionalidad tambi茅n se puede hacer con componentes de clase, por ejemplo.

Para ampliar m谩s del tema tambi茅n les comparto este video
useContext

Les comparto este videotutorial donde se explica un poco m谩s a profundidad lo que puede lograrse con useContext https://www.youtube.com/watch?v=lSMBhUEVK8k

Hola a todos, mi aporte es algo muy parecido a lo que publico @Antonio Jolse Hernandez Medina pero con unas peque帽as variaciones.

Lo primero es crear en la carpeta Context nuestro archivo ThemeContext.js con el siguiente c贸digo:

import { createContext, useState } from 'react';
const ThemeContext = createContext();

const ThemeProvider = ({children}) => {

  const [theme, setTheme] = useState("red");
  return (
    <ThemeContext.Provider value={{
        theme,
        setTheme
      }
    }>
      {children}
    </ThemeContext.Provider>
  )
}

export { ThemeContext };
export default ThemeProvider;

Despu茅s de esto buscamos en donde queremos envolver nuestros componentes con este context y hacemos lo siguiente (para nuestro caso lo vamos hacer en el archivo index.js ya que queremos que este componente envuelva a todos los dem谩s componentes):

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import ThemeProvider from './context/ThemeContext';

ReactDOM.render(
  <React.StrictMode>
    <ThemeProvider>
      <App />
    </ThemeProvider>
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

Ya con la configuraci贸n lista del context y envolviendo nuestros componentes dentro de nuestro context, generamos un hook personalizado en el cual se va a encargar de devolver los valores de nuestro context(Propiedades y m茅todos). para ello creamos una carpeta llamada hooks y dentro de ella creamos un archivo llamado useTheme.js con el siguiente c贸digo:

import { useContext } from 'react';
import { ThemeContext } from '../context/ThemeContext';

const useTheme = () => {
  return useContext(ThemeContext);
}

export default useTheme;

Con este c贸digo nos estamos evitando tener que repetir la siguiente l铆nea de c贸digo adem谩s del import de useContext en todos los componentes en donde necesitemos obtener los valores del contexto.

import { useContext } from 'react';
import { ThemeContext } from '../context/ThemeContext';
useContext(ThemeContext);

Ye teniendo el archivo useTheme.js configurado solo resta utilizarlo en todos los componentes donde necesitemos obtener los valores de este contexto como muestra la siguiente l铆nea de c贸digo:

import useTheme from '../hooks/useTheme';
const { theme } = useTheme();

NOTA: Como pueden observar aqu铆 hacemos una desestructuraci贸n de los valores de nuestro contexto, que para el caso solo utilizamos theme, pero si quisi茅ramos utilizar los dem谩s valores como setTeheme, solo es agregarlos a la desestructuraci贸n.

Para nuestro caso lo vamos a utilizar en el componente Header como se muestra a continuaci贸n.

mport { useState } from 'react'
import useTheme from '../hooks/useTheme';

const Header = () => {
  
  const [darkMode, setDarkMode] = useState(false);

  const handleClick = () => {
    setDarkMode(!darkMode);
  }

  const { theme } = useTheme();

  return (
    <div className="heder">
      <h1 style={{color: theme}}>React Hooks</h1>
      <button type="button" onClick={handleClick}>
        {
          darkMode ? "Ligth Mode" : "Dark Mode"
        }
      </button>
      <button type="button" onClick={() => { setDarkMode(!darkMode) }}>
        {
          darkMode ? "Ligth Mode 2" : "Dark Mode 2"
        }
      </button>
    </div>
  );
}
 
export default Header

Y eso es todo lo que tendr铆amos que realizar para configurar nuestro contexto espero les sirva de mucha ayuda. Cabe aclarar que se podr铆a evitar realizar el paso de crear el hook personalizado, creo que ya son gustos y formas de programar y aunque solo son un par de l铆neas de c贸digo que solo te evitar铆as repetir, cuando ya lo utilizas en muchos componentes es donde realmente ves que te estas evitando repetir el mismo c贸digo siempre.

  • context permite poder pasar valores entre componentes sin tener que hacerlo por props
  • Al usar createContext el valor por defecto que le pasamos solo es usado 煤nicamente si no hay un Provider.
    Nota: pasar undefined como valor al Provider no hace que los componentes que lo consumen utilicen defaultValue

Gracias al aporte de un compa帽ero consegu铆 montar el context para ejecutar el cambio de modo Dark a Light


C贸digo

Hola! Yo lo hice de la siguiente manera, en el archivo de ThemeContext cre茅 el contexto 鈥楾hemeContext鈥, adem谩s cre茅 una funci贸n llamada ThemeProvider, que retorna el provider con el valor que se quiere retornar. Y por 煤ltimo cree mi propio hook de useTheme, que hace uso del contexto de 鈥楾hemeContext鈥 y retorna el valor previamente asignado en el ThemeProvider. De la siguiente manera:

Siento que es mejor tenerlo de esta forma, porque luego en el index, solamente necesito encapsular el componente de APP con la funci贸n de 鈥楾hemeProvider鈥, de la siguiente manera:

Ahorita el value del provider es estatico, solamente retorna la palabra 鈥榞reen鈥, pero suponiendo que el value es un objeto con funciones y m谩s atributos, se puede escribir toda esa l贸gica dentro del m茅todo 鈥楾hemeProvider鈥 y quedar铆a mejor.

Por 煤ltimo, luego de encapsular el componente App con 鈥楾hemeProvider鈥, ya toda la app tiene acceso a este contexto, y recordando que creamos nuestro propio hook de 鈥榰seTheme鈥, ya dicho m茅todo, hace uso del metodo 鈥榰seContext鈥 y retorna el valor del contexto, por lo tanto, si queremos utilizar el contexto en otro componente, solamente es necesario importar el hook de 鈥榰seTheme鈥, de la siguiente manera:

import React, { createContext, useState } from "react";

export const theme = {
  dark: {
    background: "black",
    color: "white"
  },
  light: {
    background: "white",
    color: "black"
  }
};

export const ThemeContext = createContext();

export const ContextProvider = (props) => {
  const [stateTheme, setTheme] = useState(false);
  const value = { stateTheme, setTheme, theme };

  return <ThemeContext.Provider value={value} {...props} />;
};
> > 


Cambiando el modo, de oscuro a normal y viceversa, usando useContext

// ThemeContext.js
import React from "react";

const toggleDarkModel = () => {};

const theme = {
	darkModeActive: false,
	toggleDarkModel,
};

const ThemeContext = React.createContext(theme);

export default ThemeContext;
// App.js
import React, { useState } from "react";

import "./App.css";
import ThemeContext from "./context/ThemeContext";
import Header from "./components/Header";
import Cryptos from "./components/Cryptos";

let mode = false;
if (window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches) {
	mode = true;
}

function App() {
	const [darkModeActive, setDarkModeActive] = useState(mode);
	const toggleDarkModel = () => {
		setDarkModeActive(!darkModeActive);
	};
	return (
		<ThemeContext.Provider value={{ toggleDarkModel, darkModeActive }}>
			<div className={`App ${darkModeActive ? "dark-mode" : "light-mode"}`}>
				<section className="section">
					<Header />
					<div className="container is-flex is-flex-direction-row is-align-content-center is-justify-content-center is-flex-wrap-wrap">
						<Cryptos />
					</div>
				</section>
			</div>
		</ThemeContext.Provider>
	);
}

export default App;
// Header.jsx
import React, { useContext } from "react";
import ThemeContext from "../context/ThemeContext";

const Header = () => {
    const { toggleDarkModel, darkModeActive } = useContext(ThemeContext);
    return (
        <div className="Header container">
            <h1 className="title">Crypto Swag</h1>
            <button onClick={toggleDarkModel} className={`button is-small ${darkModeActive ? "is-white" : "is-dark"}`}>
                <span className="icon is-small">
                    <i className={`mdi ${darkModeActive ? "mdi-lightbulb-on" : "mdi-lightbulb-off"}`}></i>
                </span>
            </button>
        </div>
    );
};

export default Header;

Asi va mi proyecto con un poco de dise帽o y algunas mejoras en cuanto a el funcionamiento. Para aprender tambien hay que practicar!!!

![](

Bueno haciendo la tarea
DarkMode

LigthMode

Me esta gustando este ejercicio esta quedando excelente

Yo encontr茅 esta forma de usar combinados el useState y useContext para poder actualizar el DarkMode.
En el App.jsx importe el ThemeContext y envolv铆 la App pasando como value un estado establecido con useState y una funci贸n que actualiza ese estado:

import React, { useState } from 'react';
import Header from './components/Header';
import Characters from './components/Characters';
import ThemeContext from './context/ThemeContext';

function App() {
  const [theme, updateTheme] = useState('light-mode');
  function setTheme(newTheme) {
    updateTheme(newTheme);
  }
  return (
    <ThemeContext.Provider value={{ theme, setTheme }}>
      <div className="App">
        <Header />
        <Characters />
      </div>
    </ThemeContext.Provider>
  );
}

export default App;

Despu茅s en el Header.jsx traje el context y qued贸 de esta manera:

import React, { useState, useContext } from 'react';
import ThemeContext from '../context/ThemeContext';

const Header = () => {
  const [darkMode, setDarkMode] = useState(false);
  const { theme, setTheme } = useContext(ThemeContext);
  const handleClick = () => {
    if (theme === 'light-mode') {
      setTheme('dark-mode');
      document.querySelector('body').classList.add('dark-mode');
    } else {
      setTheme('light-mode');
      document.querySelector('body').classList.remove('dark-mode');
    }
    setDarkMode(!darkMode);
  };
  return (
    <div className="Header row">
      <h1>StarWars Characters API</h1>
      <button className="DarkModeButton" type="button" onClick={handleClick}>
        {darkMode ? 'Light Mode' : 'Dark Mode'}
      </button>
    </div>
  );
};

export default Header;

Aqu铆 les dejo mi reto!

Pude lograr el reto pasado con esta clase. Les comparto mi c贸digo.

App.jsx

Hader.jsx

css

.lightmode {
  background-color: beige;
}

.darkmode {
  background-color: midnightblue;
  color: white;
}
import React, { useState } from 'react';

const ThemeContext = React.createContext({ isDark: null, toggleTheme: () => null });

const CACHE_KEY = 'IS_DARK';

const ThemeContextProvider = ({ children }) => {
    const [isDark, setIsDark] = useState(() => {
        const isDarkUserSetting = localStorage.getItem(CACHE_KEY)
        return isDarkUserSetting ? JSON.parse(isDarkUserSetting) : false
    })

    const toggleTheme = () => {
        setIsDark((prevState) => {
            localStorage.setItem(CACHE_KEY, JSON.stringify(!prevState));
            return !prevState;
        })
    }

    return (
        <ThemeContext.Provider value={{ isDark, toggleTheme }}>
            { children }
        </ThemeContext.Provider>
    )

}

export { ThemeContext, ThemeContextProvider };```

ThemeContext.j

import React, { createContext, useState  } from "react";
import styled from 'styled-components';

const ThemeContext = createContext({});

export const Card = styled.div`
 background-color: ${props => props.dark ? '#8C71B0' : 'papayawhip'};
 color:  ${props => props.dark ? '#202020' : 'palevioletred'};
`;

export function ThemeContextProvider({children}){
    const [darkMode, SetDarkMode] = useState(false);

    return (
        <ThemeContext.Provider value={{darkMode, SetDarkMode}}>
            {children}
        </ThemeContext.Provider>
    );
}

export default ThemeContext;```

Hice un tutorial de como usar React Context y Local Storage al mismo tiempo ve a verlo

Al igual que algunos compa帽eros cambie de lugar el provider, y use el hook de useState para cambiar el provider.

Pueden revisar el c贸digo desde mi github https://github.com/zurita-dev/React-Hooks/tree/useContext

驴Alguien sabe porque no funciona el Context en el primer render en produccci贸n? Lanc茅 una app en gatsby, de ejemplo, us茅 context para el dark-mode (como default) pero lo toma como undefined en el primer render

los hooks, podrian reemplazar la funcionalidad de redux?

Yo lo hice de esta forma :

Yo lo hice de esta manera :

Me tom贸 algo de rato procesar lo que estaba haciendo pero reto completado

Entonces la diferenca de Redux y useContext es que con este ultimo puedes crear varios 鈥淪tore鈥 como source???