Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Utilizando React Hooks

Estou fazendo os exercícios utilizando componentes funcionais, porém não estou conseguindo captar as informações passadas pelo formulário para o componente para renderizar a tabela. Segue abaixo meu código.

import React, { useState } from 'react';

const Form = (props) => {
  const [state, setState] = useState([
    {
      nome: '',
      livro: '',
      preco: '',
    },
  ]);

  const submit = () => {
    console.log(props.recebeAutor(state));
    console.log(setState(useState));
  };

  const handleChange = (event) => {
    const { name, value } = event.target;
    setState({
      fields: { name: '' },
    });
  };

  const { nome, livro, preco } = state;

  return (
    <form>
      <label htmlFor='nome'>Nome</label>
      <input
        id='nome'
        type='text'
        name='nome'
        value={nome}
        onChange={handleChange}
      ></input>
      <label htmlFor='livro'>Livro</label>
      <input
        id='livro'
        type='text'
        name='livro'
        value={livro}
        onChange={handleChange}
      ></input>
      <label htmlFor='preco'>Preço</label>
      <input
        id='preco'
        type='number'
        name='preco'
        value={preco}
        onChange={handleChange}
      ></input>

      <button onClick={submit} type='button'>
        Salvar
      </button>
    </form>
  );
};

export default Form;
4 respostas
solução!

Olá Ana Carolina, tudo bem com você?

Acredito que o problema está na maneira como você fez o seu setState, acredito que o ideal seria fazer da seguinte forma:

    const [state, setState] = useState({
        nome: "",
        livro: "",
        preco: "",
    });

Não precisamos de um array para definir o estado, dado que temos podemos adicionar apenas um livro por vez

E na hora de fazer a atribuição é sempre bom recopiar o estado atual e fazer as mudanças necessárias, no caso:

    const handleInputChange = event => {
        const { name, value } = event.target;
        setState({ ...state, [name]: value });
    }

Veja que no setState eu estou utilizando spread para ter o estado original e altero apenas a propriedade e valor :)

Além disso quando utilizamos o setState para atribuir um novo valor o ideal é que seja utilizado a mesma estrutura inicial, sem adicionar uma nova propriedade como você fez com o fields :)

Eu fiz download do projeto e recriei o formulário de maneira funcional, e está atualizando normalmente, o resultado final ficou assim:

import React, { useState } from 'react';

const Formulario = (props) => {

    const [state, setState] = useState({
        nome: "",
        livro: "",
        preco: "",
    });

    const submitFormulario = () => {
        props.escutadorDeSubmit(state);
        setState({...state, nome: "", livro: "", preco: ""});
    }

    const handleInputChange = event => {
        const { name, value } = event.target;

        setState({ ...state, [name]: value });
    }

    return (
        <form>
            <label htmlFor="nome">Nome</label>
            <input
                id="nome"
                type="text"
                name="nome"
                value={state.nome}
                onChange={handleInputChange} />
            <label htmlFor="livro">Livro</label>
            <input
                id="livro"
                type="text"
                name="livro"
                value={state.livro}
                onChange={handleInputChange} />
            <label htmlFor="preco">Preço</label>
            <input
                id="preco"
                type="text"
                name="preco"
                value={state.preco}
                onChange={handleInputChange} />
            <button onClick={submitFormulario} type="button">Salvar
                </button>
        </form>
    );
}
export default Formulario

Abraços e Bons Estudos!

Tentei colocar o seu código ao meu, porém agora esta surgindo este erro: TypeError: props.autores.map is not a function TableBody

  1 | import React from 'react';
  2 | 
  3 | const TableBody = (props) => {
> 4 |   const linhas = props.autores.map((linha, index) => {
  5 |     return (
  6 |       <tr key={index}>
  7 |         <td>{linha.nome}</td>

Então Ana,

Provavelmente o problema deve estar com o state do app.jstambém, e ao dar um submit você não deve estar tendo mais um array, e dessa forma não conseguimos dar um autores.map o ideal seria algo assim:

Eu peguei o projeto e transformei todos os arquivos até essa aula em componententes funcionais e está funcionando normalmente, vou deixar o link aqui para que você possa dar uma olhada no github :)

Veja que algumas vezes ao invés de pegar props.autores eu utilizo o destructuring para pegar apenas a propriedade que eu quero :)

Mas o seu estado principal deveria ser algo assim:

  const [autores, setAutores] = useState([
    {
      nome: 'Paulo',
      livro: 'React',
      preco: '1000'
    },
    {
      nome: 'Daniel',
      livro: 'Java',
      preco: '99'
    },
    {
      nome: 'Marcos',
      livro: 'Design',
      preco: '150'
    },
    {
      nome: 'Bruno',
      livro: 'DevOps',
      preco: '100'
    }
  ]);

  const removeAutor = index => {
    setAutores( autores.filter( (autor, posAtual) => {
      return posAtual !== index;
    }));
  }

  const escutadorDeSubmit = autor => {
    setAutores([...autores, autor]);
  }

  return (
    <div>
      <Tabela autores={autores} removeAutor={removeAutor}/>
      <Formulario escutadorDeSubmit={escutadorDeSubmit}/>
    </div>
  );

};

Abraços e Bons Estudos!

Muito obrigado! O problema era realmente a função recebeAutor que estava anteriormente assim:

const recebeAutor = (autor) => {
    setAutores({ autores: [...autores, autor] });
  };