i'm rendering an string array 'options' as this
<View ref={refInput}>
{options.map((item, index) => (
<View key={index}>
<View style={{ display: "flex", flexDirection: "row" }}>
<TextInput placeholder={item}></TextInput>
{options.length > 2 && index === options.length - 1 && (
<TouchableOpacity onPress={removeOption}>
<Text>Remover</Text>
</TouchableOpacity>
)}
</View>
{index >= options.length - 1 && index < 3 && (
<TouchableOpacity onPress={() => addOption(index)}>
<Text>Adicionar</Text>
</TouchableOpacity>
)}
</View>
))}
</View>
For each element in my array i'm rendering a text input. It starts with 2 and can go up to 4 inputs. What is the best way to get those inputs values?
I passed a ref to the first View that renders the map and i have a function that get that ref by
const input = refInput.current
It returns to me a HTML collection that's a bit complicated to iterate and i don't even know how to type it with typescript.
So is there a better way to get the values?
CodePudding user response:
You could store the input values inside a state. Since you have multiple inputs that you generate dynamically inside a loop, we could store these states inside a state array and induce a bijection between indices and input values.
Here is one possible implementation using your initial code as a basis.
const [values, setValues] = useState([]);
React.useEffect(() => {
setValues(options.map(item => ""));
}, [options])
function handleTextChange(index, newValue) {
setValues(prev => prev.map((val, i) => index === i ? newValue : val))
}
<View ref={refInput}>
{options.map((item, index) => (
<View key={index}>
<View style={{ display: "flex", flexDirection: "row" }}>
<TextInput onChangeText={(newValue) => handleTextChange(index, newValue)} value={values[index]} placeholder={item}></TextInput>
{options.length > 2 && index === options.length - 1 && (
<TouchableOpacity onPress={removeOption}>
<Text>Remover</Text>
</TouchableOpacity>
)}
</View>
{index >= options.length - 1 && index < 3 && (
<TouchableOpacity onPress={() => addOption(index)}>
<Text>Adicionar</Text>
</TouchableOpacity>
)}
</View>
))}
</View>