Search code examples
reactjsarraysreact-nativereact-hooksmern

In react-native how do I update a nested value in an array?


A user selects the needed type for the data entry form using a react-native SelectDropdown

  {/* Select Dropdown creates a TextInput */}
 <SelectDropdown data={types} onSelect={handleSelect} placeholder="Add a field" />

 
 const [needsAnotherInput, setNeedsAnotherInput] = useState(false)
 //Sets the needed type
 const [neededInput, setNeededInput] = useState ([]);  
 //SelectDropdown data
 const types = ['Electric', 'Gas', 'Water'];

 //sets the addedField array to be sent to the Server
 const [addedField, setAddedField] = useState([]);

  //Creates needed input
  const handleSelect = (type) =>{
    setNeedsAnotherInput(true);
    setNeededInput([...neededInput, type]);
    setAddedField([...addedField,  {field: type, read: null}]);
  }

  //Here is where the read gets added to the state object addedField
  const handleAddedFields = (read) =>{
    setAddedField({...addedField, read: read})
  }

The TextInput returns as expected

{needsAnotherInput ? neededInput.map((needed =>{
        return <>
        <TextInput 
        key={needed} 
        value={addedField} 
        name={needed} 
        onChangeText={handleAddedFields} 
        style={styles.textInput} 
        placeholder={needed} />
        </>
      })): null}

My problem lies when I tried to update the "read" value inside of the object

  addedField: [
    { field: 'Electric', read: null },
    { field: 'Gas', read: null },
    { field: 'Water', read: null }
  ]
}

Here is the submit function that sends data over to the server

//Currently the submit button sends the location to the server to to be stored in MongoDB along with the user token for AUTH
  const handleSubmit = () => {
    const fetchReq = async () => {  
      const requestOptions = {
        method: 'post',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({addedField})
      }
      //Enpoint just console.logs the request body 
      fetch('http://10.0.2.2:5000/test', requestOptions)
    }
    fetchReq();
  }

The "read" value does not update correctly, here is the object sent to the server

addedField: {
    '0': { field: 'Electric', read: null },
    '1': { field: 'Gas', read: null },
    '2': { field: 'Water', read: null },
    read: '123'
  }
}

Solution

  • I might be misunderstanding what you're trying to do, but I think you need to try:

    const handleAddedFields = (read , index) =>{
      setAddedField(prev=>prev.map((field,i)=>{
        if(index === i){
          return {...field, read: read}
        }
        return field
      })
    }
    //...
    {needsAnotherInput ? neededInput.map((needed,i) =>{
        return <>
        <TextInput 
        key={needed} 
        value={addedField} 
        name={needed} 
        onChangeText={(val)=>handleAddedFields(val, i)} 
        style={styles.textInput} 
        placeholder={needed} />
        </>
      })): null}