Browse array of React objects

Asked

Viewed 169 times

2

I intend within my parent component to create a function that will scroll through all objects stored in the state of this same component, checking whether the given parameter is equal to the value id of the object.

In my child component I intend to use this function of the parent component indicating a value as parameter and in case that parameter equals the value id, return true.

This boolean value will be used inside a if in this child component.

The function I tried to create in the parent component:

function validarId(novaId){
  Cadastros.map(cadastro => () => {
    if(cadastro.id == novaId){
      return true
    } else {
      return false
    }
  })
}

Attempt to implement the function within a conditional:

else if(validarId(id)){
  window.alert("Id já cadastrada!")
}

Full application:

Component Pai:

import './App.css';
import React, {useState} from 'react';
import {Table, Jumbotron} from 'react-bootstrap'
import Formulario from './Formulario'
import renderCadastros from './renderCadastros'

function App() {
  
  const [Cadastros, setCadastros] = useState([{
    "id": 1,
    "nome": "Francisca Julia da Costa",
    "cpf": "457.696.936-65",
    "rg": "47.360.897-2",
    "data_nasc": "23/03/1944",
    "sexo": "Feminino"
  },
  {
    "id": 2,
    "nome": "Noah Felipe Silva",
    "cpf": "956.531.431-70",
    "rg": "40.974.782-8",
    "data_nasc": "11/07/1964",
    "sexo": "Masculino"
  },
  {
    "id": 3,
    "nome": "Alícia Rosângela Melo",
    "cpf": "066.291.353-18",
    "rg": "36.214.141-1",
    "data_nasc": "18/02/1978",
    "sexo": "Feminino"
  }]) 
  
  function atualizarCadastros(novoCadastro){
    setCadastros(cadastrosAtuais => {
      return cadastrosAtuais.concat(novoCadastro)
    })
  }

  function validarId(novaId){
    Cadastros.map(cadastro => () => {
      if(cadastro.id == novaId){
        return true
      }
      else {
        return false
      }
    })
  }

  return (
  <Jumbotron style={{background: 'transparent'}}> 
    <Formulario validarId={validarId} atualizarCadastros={atualizarCadastros} />
    <Table striped bordered hover size='sm'>
      <thead>
        <tr>
          <th>Id</th>
          <th>Nome</th>
          <th>CPF</th>
          <th>RG</th>
          <th>Nascimento</th>
          <th>Sexo</th>
          <th></th>
        </tr>
      </thead>
      <tbody>
        {Cadastros.map(renderCadastros)}
      </tbody>
    </Table>
  </Jumbotron>
  
  );
}

export default App;

Child component:

import './App.css';
import React, {useRef} from 'react';
import {Button, Form, Col} from 'react-bootstrap'

function Formulario ({atualizarCadastros, validarId}){
  const refId = useRef()
  const refNome = useRef()
  const refCpf = useRef()
  const refRg = useRef()
  const refNascimento = useRef()
  const refSexo = useRef()

  function registrarCadastros(){
    const id = refId.current.value
    const nome = refNome.current.value
    const cpf = refCpf.current.value
    const rg = refRg.current.value
    const nascimento = refNascimento.current.value
    const sexo = refSexo.current.value

    const novoCadastro = {'id': id, 'nome': nome, 'cpf': cpf, 'rg': rg, 'data_nasc': nascimento, 'sexo': sexo}

    if(id == '' || nome == '' || cpf == '' || rg == '' || nascimento == '' || sexo == '' ){
      window.alert("Existem campos em branco!")
    }

    else if(validarId(id)){
      window.alert("Id já cadastrada!")
    }

    else{
    atualizarCadastros(novoCadastro)

    refId.current.value = null
    refNome.current.value = null
    refCpf.current.value = null
    refRg.current.value = null
    refNascimento.current.value = null
    refSexo.current.value = null
    }
  }

  return(
    <div>
    <Form>
    <Form.Row>
      <Col>
        <Form.Label>Identificação</Form.Label>
        <Form.Control ref={refId} placeholder="Id" />
      </Col>
      <Col>
        <Form.Label>Nome Completo</Form.Label>
        <Form.Control ref={refNome} placeholder="João Silva" />
      </Col>
      <Col>
        <Form.Label>CPF</Form.Label>
        <Form.Control ref={refCpf} placeholder="000.000.000-00" />
      </Col>
      <Col>
        <Form.Label>RG</Form.Label>
        <Form.Control ref={refRg} placeholder="0.000.000" />
      </Col>
      <Col>
        <Form.Label>Data de Nascimento</Form.Label>
        <Form.Control ref={refNascimento} placeholder="DD/MM/AAAA" />
      </Col>
      <Col>
        <Form.Label>Sexo</Form.Label>
        <Form.Control ref={refSexo} placeholder="Masculino/Feminino" />
      </Col>
    </Form.Row>
    </Form>
    <div  style={{display: 'flex', flexDirection: 'column', alignItems: 'center'}}>
      <Button onClick={registrarCadastros} style={{margin: '10px'}} variant="primary">Cadastrar</Button>
    </div> 
  </div>
  )  
}

export default Formulario

Other component of the application:

import './App.css';
import React from 'react';
import {Button} from 'react-bootstrap'

function renderCadastros(cadastro, index){
    return(
    <tr id={cadastro.id} key={index}>
        <td>{cadastro.id}</td>
        <td contentEditable="true" suppressContentEditableWarning={true}>{cadastro.nome}</td>
        <td contentEditable="true" suppressContentEditableWarning={true}>{cadastro.cpf}</td>
        <td contentEditable="true" suppressContentEditableWarning={true}>{cadastro.rg}</td>
        <td contentEditable="true" suppressContentEditableWarning={true}>{cadastro.data_nasc}</td>
        <td contentEditable="true" suppressContentEditableWarning={true}>{cadastro.sexo}</td>
        <td align="center"><Button variant="danger">Excluir</Button></td>
    </tr>)
  }

  export default renderCadastros
  • could you explain better? does not have a reasonable minimum example to give an answer

  • I edited the post with the entire application, thank you!

  • I want it to be possible to block the registration with an ID that already exists

  • I can’t understand what you really want to do?

  • The function registrarCadastros() creates a row in the table with the values entered in the form. then these values are entered in the useState of the parent component and then the application is rendered again. Within this function there are also some ifs that represent the constraints I want to include to add this line. One that is already done is to not let blank entries be added. And the other thing I want is that it is not allowed to add entries with id that already exist in the Usestate of the parent component

  • Then my question would be about how to check these ids that already exist in the parent Usestate and compare with the id being entered in the form

  • if you have to use filter

  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filtro

  • The biggest difficulty in the case is to be able to do this function and use it in the child component, as seen above in the code. That is, create this loop function in the "parent" and pass it as prop to the "child", and within the child use this function with the parameter I want to check. Any tips? @novic

  • The function validarId is returning an array of functions, that’s right?

  • No, the objective was for this function to map the Registry in the State of the component, verifying that the value "id" is the same as the id entered as parameter. It’s not working. @Luiz Felipe

Show 6 more comments

1 answer

1


Beauty, Diego?

Look, one point that I’ve come to realize may be having inconsistency of what is expected is in your role validarId.

The function map serves to transform an array into another, using a passed function. In your case, the function mounts an array that should look something like: [true, false, false] (imagining that the past id already exists in the first position), but it is always returning null, since there is no return value in it, and so the validation is not taking place correctly.

You can use the function some, returning true or false if a past function has any feedback true, and return that result. It would look something like this:

function validarId(novaId){
  return Cadastros.some(cadastro => () => {
    if(cadastro.id == novaId){
      return true
    } else {
      return false
    }
  })
}

The function will run the array Cadastros and, if the value of novaId is the same as any id already registered, it returns true in function, which would make it alert and not enter the else of the entries (in your form). It can be written in a simplified way also:

function validarId(novaId){
  return Cadastros.some(cadastro => cadastro.id == novaId)
}

If you can give another recommendation, make it clearer what this function does. validarId is well ok at first, but can get very vague about what will be the return of it, which can cause confusion there in the validation part itself (it is expected that the validarId return true when the id is valid or when it already exists? ). Try to use clearer names that have a logical return response, something like idExiste or something on that line, that already gives you an answer if you use the function name as 'question'.

  • First Thiago congratulations for the reply, very explanatory! Thank you very much, tonight I will implement it, then I accept your reply!!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.