jemluz / dt-money

An intermediate ReactJS project focusing on API consumption and performance (by @rocketseat)
https://dt-money-gilt.vercel.app
1 stars 0 forks source link

Conexão com a API #2

Open jemluz opened 1 year ago

jemluz commented 1 year ago

JSON Server

JSON Server é biblioteca excelente para simular uma API dentro dos seus projetos frontend.

jemluz commented 1 year ago

Requisições HTTP

No modo de desenvolvedor, suas requisições podem aparecer no devTools como sendo realizadas de modo duplicado. Isso acontece por conta do <React.StrictMode> localizado no main.jsx. O modo estrito é um modo de desenvolvedor que roda algumas verificações nos componentes do react. Por isso não estranhe em ver requisições duplicadas. Em produção isso não irá acontecer.

Anatomia de uma requisição fetch

fetch('url da requisição').then(
   resposta => ... tratamento
)

O que não fazer em uma requisição (mas funciona):

  1. Deixar os .then() aninhados. Dificulta o entendimento.

    fetch('http://localhost:3333/transactions').then(
    response => response.json().then(data => console.log(data))
    )
  2. .then( ) paralelos é melhor, mas dá para organizar ainda mais.

    fetch('http://localhost:3333/transactions')
    .then(response => response.json())
    .then(data => console.log(data))

O que fazer em uma requisição:

  1. Separar os .then( ) em variáveis
  2. Vincular os dados a um state
  3. Usar o effect para controlar as chamadas.

    const [transactions, setTransactions] = useState<Transaction[]>([]);\ 
    
    async function loadTransactions() {
    const response = await fetch('http://localhost:3333/transactions')
    const data = await response.json()
    
    setTransactions(data);
    }
    
    useEffect(() => {
    loadTransactions()
    }, [])
jemluz commented 1 year ago

Calculando resumo de transações

Anatomia da função reduce: aprenda agora e ascenda socialmente.


// final => nova estrutura de dados (em seu estado inicial)
// inicial => nova estrutura de dados (em seu estado atual/final)
// ambos final e inicial também são conhecidos como acc (accumulator / acumulador)

const summary = transactions.reduce(
    (final, objeto) => {
      // ... o que será feito

      return final;
    },
    // inicial
  )

Função reduce sendo aplicada para calcular o total de entradas, saídas e saldo de uma lista de transações:

const summary = transactions.reduce(
    (final, transaction) => {
      if (transaction.type === 'income') {
        final.income += transaction.price;
        final.total += transaction.price;
      } else {
        final.outcome += transaction.price;
        final.total -= transaction.price;
      }

      return final;
    },
    {
      income: 0,
      outcome: 0,
      total: 0
    }
  )
jemluz commented 1 year ago

Controlled components (dnovo)

Toda vez que usamos elementos não nativos do html (como o radiogroup do radix no form) para coletar dados do usuário em um form, é ideal que façamos como controled.

Se vc der um console.log() no props do atributo render do componente <Controlled /> conseguirá ver os dados que são processados.

const newTransactionSchema = z.object({
  description: z.string(),
  price: z.number(),
  category: z.string(),
  type: z.enum(['income', 'outcome']),
});

export function NewTransactionModal() {
...
const {
    control,
     ...
  } = useForm<NewTransactionFormInputs>({
    resolver: zodResolver(newTransactionSchema),
    defaultValues: {
      type: 'income'
    }
  });

return (
....
<Controller
  control={control}
  name="type"
  render={({ field }) => {
    return (
      <TransactionType
        onValueChange={field.onChange}
        value={field.value}
      >
        <TransactionTypeButton variant="income" value="income">
          <ArrowCircleUp size={24} />
          Entrada
        </TransactionTypeButton>
        <TransactionTypeButton variant="outcome" value="outcome">
          <ArrowCircleDown size={24} />
          Saída
        </TransactionTypeButton>
      </TransactionType>
    )
  }}
/>
...
)
jemluz commented 1 year ago

Buscando transações

Para add paramêtros em uma url na Fetch API, precisamos primeiro criar um objeto URL, e depois utilizar o .searchParams.append( ) para add o novo parâmetro. Onde a primeira posição recebe o nome e a segunda posição recebe o valor.

  async function fetchTransactions(query?: string) {
    const url = new URL('http://localhost:3333/transactions');

    if (query) {
      url.searchParams.append('q', query);
    }

    const response = await fetch(url);
    const data = await response.json()

    setTransactions(data);
  }
jemluz commented 1 year ago

Criando nova transação (desacoplamento)

Duplicar interfaces em locais diferentes as vezes se faz necessário, quando queremos fazer um descoplamento por exemplo (impedir a dependencia entre componentes, para manter a integridade do sistema em caso de trocas ou substituições)

Commi Conexão com a API - Criando nova transação

Nesse commit, a interface CreateTransactionInput do arquivo TransactionsContext.tsx é uma duplicação da interface por inferência NewTransactionFormInputs do arquivo NewTransactionModal/index.tsx.

Assim como a chamada da api createTransactions que tbm foi centralizada no arquivo TransactionsContext.tsx .

Se um dia eu decidir trocar o modal ou a biblioteca de form, isso "não quebra" a minha aplicação.