How to pass a specific object as props in a generation of components?

Asked

Viewed 56 times

0

Hello, I’m initiating the studies in React and when trying to create a code that generates components (in this case the "Box")where at the click of a button passing objects coming from a state to a props, party of a form, always gives Undefined value error:

ERRO:

The error occurs when trying to compile the following code:


 const [name, setName] = useState('')
 const [email, setEmail] = useState('')
 const [salario, setSalario] = useState('')

 const [ box,setBox] = useState([{nome:"name", mail:"email", sal:"salario"}])
 
 function handleGenerate(){

   setBox([...box, {name, email, salario} ])
   
   setName('');
   setEmail('');
   setSalario('');
 
   const handleChangeName= (event)=>{setName(event.target.value)}
   const handleChangeEmail= (event)=>{setEmail(event.target.value)}
   const handleChangeSalario= (event)=>{setSalario(event.target.value)}

 return(
   <React.Fragment>

     <input type="text" placeholder="Nome" value ={name} onChange={text => handleChangeName(text)}/><br/>
     <input type="text" placeholder="email" value ={email} onChange={text => handleChangeEmail(text)} /><br/>
     <input type="text" placeholder="salario" value ={salario} onChange={text => handleChangeSalario(text)} /><br/>

     <button onClick={handleGenerate}>Gerar box</button>

     {box.map((box, index)=>{
         
         return <Box key={index} index={index} name = {box[index].nome} email ={box[index].mail} salario ={box[index].sal}/>
     })
     }
   </React.Fragment>
   )
}

function Box(props){
 return(
 <div id="box">
   
   <h2>Funcionario</h2>
   <h3>nome = {props.name}</h3>
   <h3>email = {props.email}</h3>
   <h3>salario = {props.salario}</h3>
   <h3>index = {props.index} </h3>
   
 </div>
 )
}

It is important to note that each Box has to come according to the items that were placed in the inputs at the instant I click the button.

Thanks in advance and sorry for any mistake :)

  • 1

    Remove all the [index] of this passage: return <Box key={index} index={index} name = {box[index].nome} email ={box[index].mail} salario ={box[index].sal}/>

  • But when I take the index no value is passed to the Box (only Undefined)

  • That’s how you left it? return <Box key={index} index={index} name = {box.nome} email ={box.mail} salario ={box.sal}/>?

  • yes. I had even tested it like this before, but it happens like I said

2 answers

0


I believe you’re using function map incorrectly. The first parameter already returns the value of the item within the array.

{box.map((itemDeBox, index)=>{
   return <Box key={index} index={index} 
          name = {itemDeBox.nome} 
          email ={itemDeBox.mail} 
          salario ={itemDeBox.sal}/>
 })`

That’s why the name error does not exist inside an undefined value.

  • So when I use it this way it passes a Undefined to the code and keeps the same problem. I realized that he was trying to get information after "the last one" which caused the error, what I did was try to delay in 1 array this . map and then it worked (however I do not know if it would be classified as gambiarra, I would like you to look at the answer I made and answer if it is a viable option, or something complexely bad). Thank you for the reply!

  • And gabiarra yes. At some point Oce is putting wrong values inside the box array. Map() will iterate through all the items you’ve placed inside, including invalid values. I believe it might be this line setBox([...box, {name, email, salario} ]). Should be setBox([...box, {nome:name, mail:email, sal:salario} ]). You also don’t need to define values like this box[index].nome inside the map function, should be item.nome.

  • That was the mistake. If yes, select this as an answer.

0

While trying to solve the problem I realized that the map was trying to catch an object that did not yet exist, for this, I tried to make it catch before, using var === ? : (ternary operator) so he wouldn’t pick up index 0 (which was supposedly giving conflict).

Note that I also created a variable (This Liberation -> that is released when I click on the control button) so that there would not appear a first string of values with nothing on the screen (how to hide it)

So I resolved as follows:

{
         
        liberation === true? box.map((item, index)=>{
             return (index === 0?
                      undefined:
                      <Box key={index} 
                           index={index} 
                           name = {box[index].name} 
                           email ={box[index].email} 
                           salario ={box[index].salario}
                       />)
        }): undefined          
      }

when I click the button (for the first time) Liberation releases so that it can appear on the screen the BOX component:

const [liberation, setLiberation] = useState(false) //liberação para aparecer na tela os itens

function handleGenerate(){

 setBox([...box, {name, email, salario} ])
 setLiberation(true);
 
 setName('');
 setEmail('');
 setSalario('');
}

For me it worked, I don’t know if this could be considered a gambit. As I’m starting out, there are probably other more normal ways to do this kk, without using two ternary operators to divert a single problem.

Browser other questions tagged

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