1

I have a nested array of objects, each object have a nested options array like this.

const [formFields, setFormFields ] = useState({
    formTitle: '',
    fields: [
        {name: 'country', val: '', type: 'radio', options: ['Japan', 'Korea', 'usa'] },
        {name: 'state', val: '', type: 'select', options: ['texas', 'florida']},
    {name: 'location', val: '', type: 'text', options: []},
        
    ]})

Each of the items in the nested options array is supposed to be a value in a textInput which is editable. I want to be able to add/remove/edit these values inside the textInput with a button click. Please how will I be able to achieve this?

my code

 <Containter>
        {formFields.fields.map((field, index) => (
            <View key={index}>
          <View>
            <TextInput
                onChangeText={(value ) => {
                    onChange({name: field.name, value });
                    }}
                value={field.name}
            />

          </View>
              
            {(field.type === 'select' || field.type === 'radio') && (
                <>
                    {field.options.map((option) => (
                        <TextInput value={option} 
                        onChangeText={(value ) => {
                            onChange({name: field.options, ...field.options, value });
                            }}
                        
                        />
        <Text onPress={removeOption}>X</Text>
                    ))}

                    <Button title="add option" />
                </>
            )
            }
            <IconButton
                icon="delete"
                onPress={handleRemoveField}
            />

                
            </View>

        ))}
                <Button
                    onPress={handleAddField}
                    title="Add"
            
                />

               
    </Containter>
1
  • In your onChangeText you will want to call setFormFields. Commented Dec 10, 2021 at 11:30

3 Answers 3

1

Add & remove implementation:

onAdd (index,value) {
    const fields = formFields.fields.map((field,i) => { 
        if (i==index) {
           const options = [...field.options,value]
           return {...field, options}
        }
        return field
    })
    setFormFields(
        {
            ...formFields,
            fields
        }
    )
}
onRemove (index,value) {
    const fields = formFields.fields.map((field,i) => { 
        if (i==index) {
            const options = field.options.filter((item) => item != value)
            return {...field, options}
        }
        return field
    })
    setFormFields(
        {
            ...formFields,
            fields
        }
    )
}

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks so much. This works excellently well. But how do I change the values using onChange? ` {field.options.map((option) => ( <TextInput value={option} onChangeText={(value ) => { onChange({name: field.options, ...field.options, value }); }} /> ))}`
0

// in constructor
this.onChange = this.onChange.bind(this)

// in class
onChange (index,value) {
    this.setState(state => {
      const fields = state.fields.map((field,i) => { 
          if (i==index) field.val = value
          return field
      })
      return {
          ...state,
          fields
      }
    })
}


// in component 
onChangeText( (e) => onChange(index, e.target.value) )

1 Comment

Thanks for this. But what I wanted to do is to add and remove items in the field.options array. And I want to do it with react useState hooks. I'll really be glad if you can help with this.
0

For value changing:

onChange (index,value) {
  const fields = formFields.fields.map((field,i) => { 
    if (i==index) field.val = value
    return field
  })
  setFormFields({
    ...formFields,
    fields
  })
}
...
// somewhere in input element
<TextInput ... onChangeText={(e) => onChange(index,e.target.value)} .. />

2 Comments

This seems like it's ok but I'm getting an error: undefined is not an object (evaluating e.target.value)
depends on behaviour of TextInput, it seems that it passing value without event, in this case just write: onChangeText={(value) => onChange(index,value)}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.