2
respostas

Como pegar valor de um Objeto dentro de Objeto no React

Não consigo armazenar a informação digitada para enviar para API quando é uma propriedade de um objeto que está dentro de outro objeto,ex:

Venda = { id: number; vlrVenda: number; cliente: Pessoa; }

Pessoa = { id: number; nome: string; cpfCnpj: string; }

OBS: Quando digito qualquer coisa nos campos referentes aos autor o campo não é alterado, como se nada estivesse sendo digitado.

export type Processo = {
    id:         number;
    numero:     number;
    vlrCausa:   number;
    autor:      Autor;
}

export type Autor = {
    id: number; 
    nome:    string;
    cpfCnpj: string;
    tipoPessoa: string;
}
import axios, { AxiosRequestConfig } from "axios";
import { ChangeEvent, useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { Processo } from "types/processo";
import { BASE_URL } from "utils/requests";

type Props = {
    id: string;
}

function FormProcesso({ id }: Props) {

    const navigate = useNavigate();
    const [processo, setProcesso] = useState<Processo>({
        id: 0,
        numero: 0,
        vlrCausa: 0.0,
        autor: {
            id: 0,
            nome: '',
            cpfCnpj: '',
            tipoPessoa: 'AUTOR'
        }
    });

    useEffect(() => {
        if (id !== undefined) {
            findProcesso(id)
            console.log(id)
        }
    }, [id])

    function onChange(e: ChangeEvent<HTMLInputElement>) {
        setProcesso({
            ...processo,
            [e.target.name]: e.target.value,
        });
        console.log(e.target.name + ':' + e.target.value);
    }

    async function onSubmit(e: ChangeEvent<HTMLFormElement>) {
        e.preventDefault();

        const config: AxiosRequestConfig = {
            baseURL: BASE_URL,
            method: 'POST',
            url: '/processos',
            data: {
                "numero": (e.target as any).numero.value,
                "autor": {
                    "nome": (e.target as any).nome.value,
                    "cpfCnpj": (e.target as any).cpfCnpj.value,
                    "tipoPessoa": processo.autor.tipoPessoa
                },
                "vlrCausa": (e.target as any).vlrCausa.value
            }
        }
        console.log(config);
        axios(config).then(response => {
            navigate("/processos");
        });
    }

    async function findProcesso(id: String) {
        const response = await axios.get(`${BASE_URL}/processos/${id}`)
        setProcesso(response.data)
    }

    return (
        <> ..código omitido
                 <form className="row g-3" onSubmit={onSubmit}>
                        <input type="hidden" />
                        <div className="col-md-6">
                            <label className="form-label">Núm. Processo</label>
                            <input type="text" className="form-control" name="numero"
                                value={processo.numero}
                                onChange={(e: ChangeEvent<HTMLInputElement>) => onChange(e)}
                                placeholder="Digite o nome da empresa contratada" required />
                        </div>
                        <div className="col-md-6">
                            <label className="form-label">Valor da Causa</label>
                            <input type="text" className="form-control" name="vlrCausa"
                                value={processo.vlrCausa}
                                onChange={(e: ChangeEvent<HTMLInputElement>) => onChange(e)}
                                placeholder="Digite o valor da causa" required />
                        </div>
                        <div className="col-md-6">
                            <label className="form-label">Autor</label>
                            <input type="text" className="form-control" name="nome"
                                value={processo.autor.nome}
                                onChange={(e: ChangeEvent<HTMLInputElement>) => onChange(e)}
                                placeholder="Digite o nome do autor do processo" required />
                        </div>
                        <div className="col-md-6">
                            <label className="form-label">CPF / CNPJ</label>
                            <input type="text" className="form-control" name="cpfCnpj"
                                value={processo.autor.cpfCnpj}
                                onChange={(e: ChangeEvent<HTMLInputElement>) => onChange(e)}
                                placeholder="Digite o número do cpf/cnpj" required />
                        </div>                    
                    </form>
                    ...código omitido
        </>
    );
}

export default FormProcesso;
2 respostas

Salve, Andrew!

Isso acontece por conta desse código:

    function onChange(e: ChangeEvent<HTMLInputElement>) {
        setProcesso({
            ...processo,
            [e.target.name]: e.target.value,
        });
        console.log(e.target.name + ':' + e.target.value);
    }

Por exemplo o campo nome tem o seguinte input:

                        <div className="col-md-6">
                            <label className="form-label">Autor</label>
                            <input type="text" className="form-control" name="nome"
                                value={processo.autor.nome}
                                onChange={(e: ChangeEvent<HTMLInputElement>) => onChange(e)}
                                placeholder="Digite o nome do autor do processo" required />
                        </div>

Então, o seu onChange faz o seguinte:

        setProcesso({
            ...processo,
            ['nome']: e.target.value,
        });

O input não é alterado poque processo.autor.nome nunca muda. Para que isso aconteça, teria de ser algo assim:

        setProcesso({
            ...processo,
            autor: {
                nome: e.target.value,
            }
        });

Gerir todo o seu estado com uma única função de onChange pode ser basante custoso. Talvez você possa ter uma função para cada input, assim você tem mais controle sobre o que quer alterar.

Olá Marcos, entendi. Ajustei aqui o sistema e funcionou corretamente, muito obrigado. Só tive que fazer um dois ajustes, colocar o "as any" pro sistema validar e tive que colocar todos os campos do "autor" porque só com um campo o objeto "autor" ficava só com a ultima propriedade digitada. Modo 1:

function onChangeAutor(e: ChangeEvent<HTMLInputElement>) {
        setProcesso({
            ...processo,
            autor: {             
                nome: e.target.name === 'autor.nome' ? e.target.value : processo.autor.nome,
                cpfCnpj: e.target.name === 'autor.cpfCnpj' ? e.target.value : processo.autor.cpfCnpj,
                tipoPessoa: processo.autor.tipoPessoa
            }
        } as any);
    }

Modo 2:

function onChangeAutorCnpj(e: ChangeEvent<HTMLInputElement>) {
        setProcesso({
            ...processo,
            autor: {
                nome: processo.autor.nome,
                cpfCnpj: e.target.value,
                tipoPessoa: processo.autor.tipoPessoa
            }
        } as any);
        console.log(processo);
    }