Aula 13 - React - Componentes - Classes - Custom Hooks
Meus Canais
Toti:
Backing track / Play-along:
Código Fluente
Putz!
Se gostarem do conteúdo dêem um joinha 👍 na página do Código Fluente no
Facebook
Esse é o link do código fluente no Pinterest
Meus links de afiliados:
Melhore seu NETWORKING
Participe de comunidades de desenvolvedores:
Fiquem a vontade para me adicionar ao linkedin.
E também para me seguir no GITHUB.
Ah, se puder, clica na estrela nos meus repositórios pra dá uma força ao meu perfil no GITHUB
Códigos da aula
Link da documentação oficial:
Aula 13 - React - Componentes - Classes - Custom Hooks
Para o exemplo de
ganchos personalizados, vamos ter um componente
Card, onde as informações serão mostradas, e também os componentes
User e
Post.
Teremos
dois Cards na tela, o de
cima mostra o
username e o
name de um usuário de
id especificado e o
Card debaixo, mostra o
title e o
body de um post de
id especificado.
Lembrando que estamos pegando as informações
fake do:
jsonplaceholder.typicode.com/.
Você pode baixar o código zipado
Extrair ele e entrar na pasta onde extraiu.
Ou clonar o repositório e entrar na pasta.
git clone git@github.com:toticavalcanti/react-custom-hook-example.git
cd react-custom-hook-example.git
O projeto foi gerado usando:
npx create-react-app npx create-react-app
Dentro da pasta é só instalar as dependências usando:
npm install
Ou
yarn install
Os arquivos:
src/index.js
import React, {StrictMode} from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
ReactDOM.render(
<StrictMode>
<App />
</StrictMode>,
document.getElementById('root')
);
src/app.js
import React from 'react';
import User from './components/user/user.component';
import Post from './components/post/post.component';
import './App.css';
const App = props => {
return (
<div className='App'>
<User userId={5} />
<Post postId={15} />
</div>
);
};
export default App;
Componente Card
O
children é porque tanto as informações do
Post quanto o
User, serão exibidas dentro de um
Card.
Portanto,
Post e
User são
children do
Card, que por sua vez, precisa da prop
children, para acessar as informações do
Post e do
User, e exibir dentro de si.
src/components/card.component.jsx
import React from 'react';
import './card.css';
const Card = ({ children }) => <div className='card'>{ children }</div>;
export default Card;
CSS do Card
src/components/card.css
.card {
background-color: lightPINK;
min-width: 300px;
max-width: 600px;
min-height: 180px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 10px;
flex-direction: column;
padding: 30px;
font-size: 20px;
}
.card > button {
background-color: white;
border: 1px solid black;
cursor: pointer;
border-radius: 5px;
min-width: 90px;
min-height: 30px;
font-size: 16px;
margin: 10px 0;
padding: 10px;
}
Componente Post
src/components/post.component.jsx
import React, {useState, useEffect} from 'react';
import Card from '../card/card.component';
const Post = ({ postId }) => {
const [post, setPost] = useState(null);
useEffect(() => {
const fetchPost = async() => {
const res_posts = await fetch(`https://jsonplaceholder.typicode.com/posts?id=${postId}`);
const posts = await res_posts.json()
setPost(posts[0]);
}
fetchPost()
})
return (
<Card>
{post ? (
<div>
<h3> {post.title} </h3>
<p> {post.body} </p>
</div>
) : (
<p> No post found </p>
)}
</Card>
);
};
export default Post;
Componente User
src/components/user.component.jsx
import React, {useState, useEffect} from 'react';
import Card from '../card/card.component';
const User = ({ userId }) => {
const [user, setUser] = useState(null)
useEffect(() => {
const fetchUser = async() => {
const res_users = await fetch(`https://jsonplaceholder.typicode.com/users?id=${userId}`);
const users = await res_users.json()
setUser(users[0]);
}
fetchUser();
})
return (
<Card>
{user ? (
<div>
<h3>{user.username}</h3>
<p>{user.name}</p>
</div>
) : (
<p>Usário não encontrado</p>
)}
</Card>
);
};
export default User;
Perceba no código acima, que as partes marcada em azul, são praticamente iguais, o que muda é o final da url.
O que iremos fazer é centralizar esse código em um efeito reutilizável, um
custom hook, e injetar nos nossos componentes
Post e
User.
Crie uma pasta chamada
effects e dentro o arquivo
use-fetch.effect.js.
src/effects/use-fetch.effect.js
import { useState, useEffect } from 'react';
const useFetch = url => {
const [data, setData] = useState(null);
useEffect(() => {
const fetchData = async () => {
const res = await fetch(url);
const dataArray = await res.json();
setData(dataArray[0]);
};
fetchData();
}, [url]);
return data;
};
export default useFetch;
Passamos a
url no segundo parâmetro do
userEffect() porque queremos que ele só seja disparado quando a
url mudar.
Agora modifique os componentes Post e User para receber esse hook.
src/components/post.component.jsx
import React from 'react';
import Card from '../card/card.component';
import useFetch from '../../effects/use-fetch.effect';
const Post = ({ postId }) => {
const post = useFetch(
`https://jsonplaceholder.typicode.com/posts?id=${postId}`
);
return (
<Card>
{post ? (
<div>
<h3> {post.title} </h3>
<p> {post.body} </p>
</div>
) : (
<p> No post found </p>
)}
</Card>
);
};
export default Post;
Componente User
src/components/user.component.jsx
import React, {useState, useEffect} from 'react';
import Card from '../card/card.component';
import useFetch from '../../effects/use-fetch.effect';
const User = ({ userId }) => {
const user = useFetch(
`https://jsonplaceholder.typicode.com/users?id=${userId}`
);
return (
<Card>
{user ? (
<div>
<h3>{user.username}</h3>
<p>{user.name}</p>
</div>
) : (
<p>Usário não encontrado</p>
)}
</Card>
);
};
export default User;
Ficamos por aqui, até a próxima. ;)
Toti:
Backing track / Play-along:
Código Fluente
Putz!
Se gostarem do conteúdo dêem um joinha 👍 na página do Código Fluente no
Facebook
Esse é o link do código fluente no Pinterest
Meus links de afiliados:
Códigos da aula
Se gostarem do conteúdo dêem um joinha 👍 na página do Código Fluente no
Facebook
Link do código fluente no Pinterest
Obrigado, até a próxima e bons estudos. ;)