realmente el dominio del framework del profesor es increíble!
Introducción al curso avanzado de React
Qué necesitas para este curso y qué aprenderás sobre React.js
Proyecto y tecnologías que usaremos
Preparando el entorno de desarrollo
Clonando el repositorio e instalando Webpack
Instalación de React y Babel
Zeit es ahora Vercel
Linter, extensiones y deploy con Now
Creando la interfaz con styled-components
¿Qué es CSS-in-JS?
Creando nuestro primer componente: Category
Creando ListOfCategories y estilos globales
Usar información real de las categorías
Creando PhotoCard y usando react-icon
SVGR: de SVG a componente de ReactJS
Creando animaciones con keyframes
Hooks
¿Qué son los Hooks?
useEffect: limpiando eventos
useCategoriesData
Usando Intersection Observer
Uso de polyfill de Intersection Observer e imports dinámicos
Usando el localStorage para guardar los likes
Custom Hooks: useNearScreen y useLocalStorage
GraphQL y React Apollo
¿Qué es GraphQL y React Apollo? Inicializando React Apollo Client y primer HoC
Parámetros para un query con GraphQL
Usar render Props para recuperar una foto
Refactorizando y usando variables de loading y error
Usando las mutaciones con los likes
Reach Router
¿Qué es Reach Router? Creando la ruta Home
Usando Link para evitar recargar la página
Creando la página Detail
Agregando un NavBar a nuestra app
Estilando las páginas activas
Rutas protegidas
Gestión del usuario
Introducción a React.Context
Creación del componente UserForm; y Hook useInputValue
Estilando el formulario
Mutaciones para registro
Controlar estado de carga y error al registrar un usuario
Mutaciones para iniciar sesión
Persistiendo datos en Session Storage
Hacer like como usuario registrado
Mostrar favoritos y solucionar fetch policy
Cerrar sesión
Mejores prácticas, SEO y recomendaciones
Últimos retoques a las rutas de nuestra aplicación
React Helmet
Midiendo el performance de nuestra app y usando React.memo()
React.lazy() y componente Suspense
Usando PropTypes para validar las props
PWA: generando el manifest
PWA: soporte offline
Testing con Cypress
Conclusiones
¡Felicidades!
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
El componente de mutation
es otro componente importante en una aplicación Apollo. Es un componente React que proporciona una función para ejecutar una mutation
de GraphQL para así alterar la data. Además, rastrea el estado de carga, finalización y error de esa mutación.
Aportes 47
Preguntas 4
realmente el dominio del framework del profesor es increíble!
Actualmente la libreria apollo se implementa como @apollo/client y esta super genial usarla como un custom hook. Les comparto el codigo
import { useMutation, gql } from '@apollo/client'
const MUTATION_LIKE_PHOTO = gql`
mutation likeAnonymousPhoto($input: LikePhoto!) {
likeAnonymousPhoto(input: $input) {
id,
liked,
likes
}
}
`
export const useMuationToogleLike = () => {
const [mutation, { loading: mutationLoading, error: mutationError }] = useMutation(MUTATION_LIKE_PHOTO)
return { mutation, mutationLoading, mutationError }
}
Para usarlo lo hacen asi
import React from 'react'
import { ImgWrapper, Img, Article } from './styles'
import { useLocalStorage } from '../hooks/useLocalStorage'
import { useNearScreen } from '../hooks/useNearScreen'
import { useMuationToogleLike } from '../hooks/useMutationToogleLike'
import { FavButton } from '../FavButton'
const DEFAULT_IMAGE = 'https://res.cloudinary.com/midudev/image/upload/w_300/q_80/v1560262103/dogs.png'
export const PhotoCard = ({ id, likes = 0, src = DEFAULT_IMAGE }) => {
const [show, element] = useNearScreen()
const { mutation, mutationLoading, mutationError } = useMuationToogleLike()
const key = `like-${id}`
const [liked, setLiked] = useLocalStorage(key, false)
const handleFavClick = () => {
!liked && mutation({
variables: {
input: { id }
}
})
setLiked(!liked)
}
// console.log('{ mutation, mutationLoading, mutationError }', { mutation, mutationLoading, mutationError })
return (
<Article ref={element}>
{
show && <>
<a href={`/?detail=${id}`}>
<ImgWrapper>
<Img src={src} />
</ImgWrapper>
</a>
<FavButton
liked={liked} likes={likes}
onClick={handleFavClick} />
</>
}
</Article>
)
}
const LIKE_PHOTO = gql`
mutation likeAnonymousPhoto($input: LikePhoto!) {
likeAnonymousPhoto(input: $input) {
id,
liked,
likes
}
}
`
JAJA ni phuhta idea de que hace el profe jajaja
Somos varios los que pensamos que el curso está bastante desactualizado por lo menos respecto a Apollo.
Así mismo y solo a título personal, me parece algo interesante tener que apelar a estudiar un poco la librería de Apollo para transformar lo que se da en el curso, pero no creo que deba ser así y hay bastante malestar en los estudiantes que están tomando el curso en este 2021, por lo menos de la segunda mitad.
Mi meta es llegar a entender y dominar reactJs de la misma forma en la que explica este profesor es excelente.
Mi version con hooks. Me base en https://www.apollographql.com/docs/react/data/mutations/#executing-a-mutation
useLikePhoto
import { gql, useMutation } from '@apollo/client'
export const useLikePhoto = (id) => {
const LIKE_PHOTO = gql`
mutation likeAnonymousPhoto($input: LikePhoto!) {
likeAnonymousPhoto(input: $input) {
id
liked
likes
}
}
`
const [toggleLike] = useMutation(LIKE_PHOTO)
return [toggleLike]
}
**PhotoCard **
const [toggleLike] = useLikePhoto()
const handleFavButtonClick = () => {
console.log(`id de la photo ${id}`)
setLiked(!liked)
toggleLike({ variables: { input: { id: id } } })
}
Para los que quieran hacerlo con apollo hooks os dejo el código del componente completo
import React, { useEffect, useRef, useState } from 'react'
import { gql } from 'apollo-boost'
import { useMutation } from '@apollo/react-hooks'
const DEFAULT_IMAGE =
'https://res.cloudinary.com/midudev/image/upload/w_300/q_80/v1560262103/dogs.png'
// Styles
import { Article, ImgContainer, Img, Button, Span } from './styles'
// Hooks
import useLocalStorage from '../../hooks/useLocalStorage'
import useNearScreen from '../../hooks/useNearScreen'
// Import const TOGGLE_LIKE
const TOGGLE_LIKE = gql`
mutation likeAnonymousPhoto($input: LikePhoto!) {
likeAnonymousPhoto(input: $input) {
id
liked
likes
}
}
`
import { IoIosHeartEmpty, IoIosHeart } from 'react-icons/io'
/* -------------------------------------------------------------------------- */
/* Component */
/* -------------------------------------------------------------------------- */
export const PhotoCard = ({ id, likes = 0, src = DEFAULT_IMAGE }) => {
const [liked, setLiked] = useLocalStorage(id, false)
const [toggleLike] = useMutation(TOGGLE_LIKE, {
variables: { input: { id } },
})
const [show, ref] = useNearScreen()
const Icon = liked ? IoIosHeart : IoIosHeartEmpty
const handleFavClick = () => {
setLiked(!liked)
toggleLike()
}
return (
<Article ref={ref}>
{show ? (
<>
<a href={`/?detail=${id}`}>
<ImgContainer id="img__container">
<Img src={src} alt="" />
</ImgContainer>
</a>
<Button onClick={handleFavClick}>
<Icon size="25px" />
{likes}
<Span>¡Dislike!</Span>
</Button>
</>
) : (
<></>
)}
</Article>
)
}
Mi código con useMutation, el hook de react apollo para las mutaciones.
const [toggleLike] = useMutation(TOOGLE_LIKE, { variables: { input: { id } } });
const handleFavClick = () => {
toggleLike()
setLiked(!liked)
}
Podríamos mejorar el nombramiento de algunas variables/params dependiendo del tipo de valor que se aloje en ellas. Por ejemplo: “liked” podría ser “isLiked” y daría a entender que es un valor booleano.
si cambiaste las dependencias apollo-boots
y react-apollo
por la dependencia @apollo/client
Para realizar la importación de Mutation
seria de la siguiente forma:
import { Mutation } from '@apollo/client/react/components'
import { gql } from '@apollo/client'
para que puedas seguir realizando el curso de la misma forma que el profesor.
Es un curso muy bueno, pero todo lo de Apollo ya está desactualizado. La api actual de Apollo hace todo con hooks. Creo que este curso debe actualizarse o hacer un curso de Apollo que non hay
Cambio muchismo la forma en como se realiza esto hoy con apollo, dejo la forma en que lo implemente, pero en serio deberian actualizar el curso
import React, { FC } from "react";
import { Img, ImgWrapper, Article } from "./styles";
import { useLocalStorage } from "../../hooks/useLocalStorage";
import { useNearScreen } from "../../hooks/useNearScrean";
import { FavButton } from "../FavButton";
import { useMutation } from "@apollo/client";
import { LIKE_PHOTO } from "../container/ToggleLikeMutation";
type props = {
id?: string;
likes?: number;
src?: string;
};
export const PhotoCard: FC<props> = ({ id, likes = 0, src }) => {
const key = `like-${id}`;
const [liked, setLiked] = useLocalStorage(key, false);
const [show, elementRef] = useNearScreen();
const [mutateFunction, { data, loading, error }] = useMutation(LIKE_PHOTO);
const handleFavClick = () => {
!liked && mutateFunction({ variables: { input: { id } } });
setLiked(!liked);
};
//if (loading) return <p>Validando...</p>;
if (error) return <p>Submission error! ${error.message}</p>;
return (
<Article ref={elementRef}>
{show && (
<>
<ImgWrapper href={`/?detail=${id}`}>
<div>
<Img src={src} />
</div>
</ImgWrapper>
<FavButton liked={liked} likes={likes} onClick={handleFavClick} />
</>
)}
</Article>
);
};
Ya no se si seguir con el curso, o dejarlo aquí, esta repleto de errores
Como podriamos hacer para que disminuya el numero de likes?
Estoy usando react apollo y tuve algunos problemas para llevar acabo este ejercicio, seguramente se pueda mejorar pero asi lo resolvi
PhotoCard
import React from 'react'
import {
ImgWrapper,
Img,
Article
} from './styles'
import { useLocalStorage } from '../../hooks/useLocalStorage'
import { useNearScreen } from '../../hooks/useNearScreen'
import { FavButton } from '../FavButton/index'
import { UseLikeMutation } from '../../graphql/useToggleLikeMutation'
const DEFAULT_IMAGE = 'https://res.cloudinary.com/midudev/image/upload/w_300/q_80/v1560262103/dogs.png'
export const PhotoCard = ({ id, likes = 0, src = DEFAULT_IMAGE }) => {
const key = `like-${id}`
const [liked, setLiked] = useLocalStorage(key, false)
const [show, ref] = useNearScreen()
const { toggleLikePhoto } = UseLikeMutation()
const handleFavClick = () => {
setLiked(!liked)
toggleLikePhoto({
variables: {
input: { id }
}
})
}
return (
<Article ref={ref}>
{show && (
<>
<a
href={`/detail/${id}`}
>
<ImgWrapper>
<Img src={src} />
</ImgWrapper>
</a>
<FavButton
liked={liked}
likes={likes}
onClick={handleFavClick}
/>
</>
)}
</Article>
)
}
useLikeMutations
import { useMutation } from '@apollo/client'
import { gql } from 'apollo-boost'
const LIKE_PHOTO = gql`
mutation likeAnonymousPhoto($input: LikePhoto!) {
likeAnonymousPhoto(input: $input) {
id,
liked,
likes
}
}
`
export const UseLikeMutation = () => {
const [toggleLikePhoto] = useMutation(LIKE_PHOTO)
return { toggleLikePhoto }
}
con hook react pollo
-useToggleLikeMutation.jsx
import { useMutation } from '@apollo/react-hooks';
import gql from 'graphql-tag';
const LIKE_PHOTO = gql`
mutation likeAnonymousPhoto($input: LikePhoto!) {
likeAnonymousPhoto(input: $input) {
id,
liked,
likes
}
}
`;
const useToggleLikeMutation = (id) => {
const [toggleLikePhoto] = useMutation(LIKE_PHOTO, { variables: { input: { id } } });
return { toggleLikePhoto };
};
export default useToggleLikeMutation;```
Sigo pensando lo mismo que cuando empecé el curso. Muy desactualizado.
Como sé que el nombre de la función debe ser toggleLike? no me quedó claro
import { Mutation } from '@apollo/client/react/components';
Desde aquí recuperamos el Componente Mutation hoy en día con “@apollo/client”
Interesante React Apollo se pdoria decir que te permite hacer lo que harias con Firebase
lo malo es que si le doy dislike no se descuenta
Hola, les dejo el avance del curso hasta este punto, hecho en Nextjs:
https://github.com/danyel117/petgram-platzi/tree/likemutation
no entiendo de donde sale toggleLike? aiuda
Les quiero compartir como hacer la mutation con hook
Buena tarde comunidad platzi les dejo mi aporte de la mutation para quitar los likes.
unlikeAnonymousPhoto: (_, { input }) => {
// find the photo by id and throw an error if it doesn't exist
const { id: photoId } = input;
const photo = photosModel.find({ id: photoId });
if (!photo) {
throw new Error(`Couldn't find photo with id ${photoId}`);
}
// remove a like to the photo
photosModel.removeLike({ id: photoId });
// get the updated photos model
const actualPhoto = photosModel.find({ id: photoId });
return actualPhoto;
},
En las mutations las registran de esta manera
unlikeAnonymousPhoto(input: LikePhoto!): Photo
creo que me gusta mas redux jaja
Graphql me recuerda un poco a Mongoose
Alguien sabe como solucionar el siguiente error?
mutationError: Error: you must be logged in to perform this action at new t (…) at Object.next
Yo tampo entiendo de donde sale - toggleLike. ?
Hay un error que ya me imaginaba que iba a ocurrir, si le das varias veces likes a foto, incrementa varias veces el número de likes (y solo debe aumentar y disminuir en 1)
Que actualice los likes automáticamente después de ejecutar la mutación me voló la cabeza…!!! 🤯
Esta fue mi manera de resolverlo con el hook useMutation() de @apollo/client
import styled from 'styled-components'
import { MdFavoriteBorder, MdFavorite } from 'react-icons/md'
import { gql, useMutation } from '@apollo/client'
import LoadingIcon from '@common/LoadingIcon'
const Button = styled.button`
display: flex;
align-items: center;
padding-top: 8px;
& svg {
margin-inline: 12px;
cursor: pointer;
}
`
export default function FavButton({liked, likes, setLiked, idPhoto}) {
const LIKE_PHOTO = gql`
mutation likeAnonymousPhoto($input: LikePhoto!) {
likeAnonymousPhoto(input: $input) {
id,
liked,
likes
}
}
`
const [likePhoto, {data, loading, error}] = useMutation(LIKE_PHOTO)
const handleLike = async () => {
await likePhoto({variables: {input: {id: idPhoto}}})
setLiked(!liked)
}
if (error) return <div>Error!</div>
return (
<Button onClick={() => handleLike()}>
{loading
? <LoadingIcon size={24}/>
: liked
? <MdFavorite color="red" size="32px"/>
: <MdFavoriteBorder color="gray" size="32px"/>
}
<span>{likes} Likes!</span>
</Button>
)
}
Es mi primer curso en platzi, y veo muy desactualizado este curso y también la vista de la grabación es incómoda con la barra exploradora abierta todo el tiempo.
Anter era muy engorroso hacer peticiones a graphql con hooks todo mas limpio y sencillo.
Me trono la cabeza con esta clase 🤯
No me quedo realmente claro, en que momento le decimos a graphql que debe aumentar un numero los likes?
Maravillado con el dinamismo que propone react con graphql, espero realizar un proyecto así algún día
totalmente extaciado con react-apollo
Esta clase fue un poco más confusa, para mi…🤦🏽♀️ figuró repetir el video
Increible el poder y el alcance que tiene react apollo y graphql. Me queda un poco la duda de como funciona mutation, pero creo que pasaré por el curso de graph para aprenderlo más, quedé enamorado
que locura de clase, se le nota la experiencia y el dominio del tema
Cuándo quitamos el like como podemos hacer que el contador baje uno?
No entendi esta claseee
a
Wuuaooo, super interesante este tema. espero ser uan expert en React. ❤️
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?
o inicia sesión.