No tienes acceso a esta clase

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

No se trata de lo que quieres comprar, sino de quién quieres ser. Invierte en tu educación con el precio especial

Antes: $249

Currency
$209

Paga en 4 cuotas sin intereses

Paga en 4 cuotas sin intereses
Suscríbete

Termina en:

11 Días
21 Hrs
9 Min
28 Seg
Curso de React.js

Curso de React.js

Juan David Castro Gallego

Juan David Castro Gallego

Reto: estados para abrir y cerrar un modal

25/34
Recursos

Aportes 22

Preguntas 2

Ordenar por:

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

Solo agregue una **función, para negar el estado actual y asignarlo al botón de agregar en el OnClick **

 const abrirModal = () => {
        setOpenModal(!openModal);
      }

y utilice el ** context global ** para el estado.

const {openModal, setOpenModal} = React.useContext(TodoContext);<code> 

Código completo:

import { TodoContext } from '../TodoContext';
import React from 'react';
import './CreateTodoButton.css';

function CreateTodoButton(){
    const {openModal, setOpenModal} = React.useContext(TodoContext);
    
    const abrirModal = () => {
        setOpenModal(!openModal);
      }


    return (        
        <div className=''>
            <div className='d-flex flex-row justify-content-center'>
                <p>
                    <span className="inputColor">
                        <input type="text" placeholder="Ingresa alguna tarea..."/>
                        <span></span>	
                    </span>
                </p>        
            </div>
            <div className='d-flex flex-row justify-content-center'>
                <div className="box-2">
                    <div className="btn btn-two" onClick={abrirModal}>
                        <span>Agregar Tarea</span>
                    </div>
                </div>
            </div>
        </div>
    );
}

export {CreateTodoButton};

Les comparto como me quedo antes y despues de dar click al CreateTodoButton. Recibo sugerencias y recomendaciones, nunca antes habia creado un modal ni mucho menos agregarle overlay.
.
Antes de abrirlo:

.
Despues de abrirlo:

Yo lo pense un poco diferente utilizando lo que ya vimos en clases anteriores.

En el archivo TodoContext/index.js cree un nuevo estado y una funcion para cambiar ese estado y la inclui en el return del Toco Context:

const [openModal, setOpenModal] = React.useState(false);

const toggleModal = () => {
	setOpenModal(!openModal)
}

    return (
        <TodoContext.Provider value={{
            loading,
            error,
            completedTodos,
            totalTodos,
            searchValue,
            setSearchValue,
            searchedTodos,
            completeTodo,
            delteTodo,
            openModal,
            setOpenModal,
            toggleModal
        }}>
            {children}
        </TodoContext.Provider>
    );

Dentro del archivo CreateButton/index.js hice lo siguiente:

import React from 'react';
import './CreateTodoButton.css';
import { TodoContext } from '../TodoContext';

function CreateTodoButton() {
    const {
        toggleModal
    } = React.useContext(TodoContext)

    return (
        <button 
            className='CreateTodoButton'
            onClick={(event) => {
                toggleModal()
            }}
        >+</button>
    );
}

export {CreateTodoButton};

Pueden usar un useEffect para identificar la tecla de ESC y cerrar el modal con el teclado

<code> React.useEffect(() => {
        const close = (e) => {
          if(e.keyCode === 27){
            setOpenModal(false);
          }
        }
        window.addEventListener('keydown', close)
      return () => window.removeEventListener('keydown', close)
    },[]);
Gente, recuerden importar sus estilos una vez los creen, para que no se pasen rato buscando un supuesto error que no existe, donde los estilos no se perciben pero es solo que uno no ha importado el css. 😂😂

Así se ve mi modal.
Y me parece genial idea la función

onClick={() => setOpenModal(state => !state)}
Yo lo que hice fué exportar el estado setOpenModal y lo usé al momento de hacer click en el componente CreateTodoButton `import { Context } from '@context';import { useContext } from 'react'` `const Create_Todo_Button = () => {  const { openModal, setOpenModal } = useContext(Context)  return (   
      <button        className="text-3xl bg-blue-600 p-4 rounded-full text-white "        onClick={() => setOpenModal(!openModal) }      >        <FiPlus />      </button>   
  );}` `export default Create_Todo_Button;`
Así va quedando, creo que luego le encontraré otra funcionalidad al Modal porque yo quiero que las tareas se agreguen desde la misma barra de texto de ahí 😂 ![]()![](https://i.postimg.cc/vZGPYTH9/demo-modal-app.gif)
Comparto mi solución al reto, algo más larga que lo que vimos en esta clase, hice un función donde tenemos el contexto con la lógica, toggleTodo() que cambia el estado y agrega/quita una clase de css para que abra/cierre el modal. Agregué unos elementos al modal para ir dando estructura sin diseño aún y con los botones de crear (sin funcionar) y cerrar (funcionando). Saludos. repo: <https://github.com/mrivero40/multitask> ![](https://static.platzi.com/media/user_upload/imagen-c3b2047a-f1f4-47f9-8a89-018c37395ca3.jpg)

Lo que yo hice fue usar el contexto en el TodoButton, no sé si será la mejor opción pero me funciona para abrir y cerrarlo

import './CreateTodoButton.css';
import { TodoContext } from '../TodoContext';
import React from 'react';

function CreateTodoButton() {
    const {openModal, 
        setOpenModal,
       } = React.useContext(TodoContext)
    return(
        
        <button onClick={()=>{
            !openModal?
            setOpenModal(true):
            setOpenModal(false)
            
        }}>+</button>
    )
}

export {CreateTodoButton}

Yo dejé el open modal como setOpenModal(true) directamente, pues el botón create todo button nunca va a cerrarlo, para eso es el botón de cerrar del modal, entonces no lo vi necesario

Mi solución fue, envíar el estado del modal al CreateTodoButton

Y en el onClick del botón, solo hice que cambiará el estado dependiendo del valor que contenía

Mi solucion al Reto fue la siguiente:
Envio a la funcion el setOpenModal y en el onClick lo utilizo para negar el openModal, enviandolo como argumento y devolviendo su valor negado.

function CreateToDoButton({setOpenModal}){
    return(
        <button className="bg-gray-700 text-white rounded-lg p-2 mt-10"
            onClick={
            () => {
                setOpenModal(openModal => !openModal)
            }} 
        >Add a New ToDo</button>
    )
}
export default CreateToDoButton;

Esta fue mi solucion para el reto del button !!

    return (
        <button onClick={(event) => {
            openModal ? 
            setOpenModal(false) :
            setOpenModal(true) 

            console.log('escuchando')
        }}>
            +
        </button>
    );
Yo, lo único que hice fue modificar mi Button así, ¿Estará bien? import React from 'react';import { TodoContext } from '../TodoContext';import './CreateTodoButton.css'; function CreateTodoButton() {  const {openModal, setOpenModal} = React.useContext(TodoContext)  return (    \<button      className="CreateTodoButton"      onClick={        (event) => {                    setOpenModal(!openModal)        }      }    >+\</button>  );} export { CreateTodoButton };
Pregunta: No me funcionó el z-index = 1 en el botón de crear ToDo. Estuve buscando que pudo haber sido el error pero todo parece en order. Lo unico que creo puede ser el error es porque el botón está mas abajo en la jerarquia en el div id=app que el modal-background en el div id=modal. ¿Alguien podría indicarme cual puede ser la solución? Gracias.
## 🦄✨En mi caso hice una estructura que consta de Header y Body para el modal. Para que se pueda añadir un título al modal y se pueda cerrar el mismo a través de una X :3. También realicé el background como un contenedor a parte para que se pueda aplicar un blur al fondo n.n ![](https://static.platzi.com/media/user_upload/image-3d6c584f-119f-4244-9ba7-f7331b4571bd.jpg)
```js import { Context } from '@context';import { useContext } from 'react' const Create_Todo_Button = () => { const { openModal, setOpenModal } = useContext(Context) return (
<button className="text-3xl bg-blue-600 p-4 rounded-full text-white " onClick={() => setOpenModal(!openModal) } > <FiPlus /> </button>
);} export default Create_Todo_Button; ``` Yo lo que hice fué exportar el estado setOpenModal y lo usé al momento de hacer click en el componente CreateTodoButton `import { Context } from '@context';import { useContext } from 'react'` `const Create_Todo_Button = () => { const { openModal, setOpenModal } = useContext(Context) return (
<button className="text-3xl bg-blue-600 p-4 rounded-full text-white " onClick={() => setOpenModal(!openModal) } > <FiPlus /> </button>
);}` `export default Create_Todo_Button;` PD: sorrypor subir dos veces lo mismo es que nunca habia comentado por aquí jeje
asi lo he dejado ![](https://static.platzi.com/media/user_upload/image-819e389a-d9da-4c1e-8f20-e81bf7e4b74d.jpg)
Si el modal se carga automáticamente sin haber sido clicado, simplemente cambie el estado de 'true' a 'false'.
No me queda claro para que utilizar el portal, no lo he agregado a mi codigo y sigue funcionando igual. Alguie me puede explicar por favor? ![](https://static.platzi.com/media/user_upload/image-c1881ad4-bb56-438f-a6e2-f1d0b2600891.jpg)![](https://ibb.co/X5XWJ1W)

No necesito un modal, ya que ya le había hecho una función createTodo

//Función
    const { item: todos,
        loadingStatus: todoStatus,
        saveItem: saveTodos
    } = useLocalStorage({ itemName: "TODOS-HACERES-V1", initialValue: [] });

    const createTodo = (text) => {
        if (text) {
            const timestamp = new Date().getTime();
            const newTodo = { id: timestamp, text, completed: false };
            saveTodos([...todos, newTodo]);
        }
    };

//Componente
function CreateTodobutton({
    inputCreateValue,
    setInputCreateValue,
    createTodo,
    totalTodos,
    todoStatus }) {

    function CreateButton() {
        createTodo(inputCreateValue)
        setInputCreateValue("");
    }
    if (todoStatus === "Ready") 
    return (
        <li className="CreateTodoButton">
            <input
                value={inputCreateValue}
                placeholder={totalTodos === 0 ? "Escribe una nueva tarea aqui" : ""}
                onChange={(event) => {
                    setInputCreateValue(event.target.value);
                }}
            />
            <BsPlus className="IconCreateTodo" onClick={CreateButton} />
        </li>
    );
}