I'm new at react-native. I'm trying to implement a little more complex calculator and I've stumbled on "unwanted" re-rendering.
Here is what I have: two functional components, the first is a Flatlist of TextInput with values, the second one is a Flatlist of Text with results.
First component stores values in an array, on each TextInput endEditing I look if the value pass the check, if so I add it to the array, then I check if the all array items have a valid value, if so I raise an event with the array.
The containing Screen, where First and Second component are, receive the First component event with the valued array, and here start the problem...
Either if I store the array in a useState for further calculations, or if I calculate the array directly and store the results in a useState for results, I get a First component re-render.
The Second component has a property where I pass the results stored in the useState results.
I understand that the Second component should rerender on "results" change, but why also the First component rerender on a simple setState for the array, or for the results?
I thought about useMemo for the First component but I get an error I can't wrap my head around.
Here code snippets: First component
export default ListInputs = ({ items = [], onChange = (parameters) => {} }) => {
// Each input item rendered by the Flatlist
const InputItem = ({ item }) => {
let values = [...items];
// On endEditing check for value validity
// If the whole array is OK raise the onChange for calculations
const handleChange = (item) => {
if (item == null) return;
const parameter = { label: item.label, value: item.value };
updateParameter(parameter);
if (checkParameters()) {
onChange(values);
}
};
return (
<TextInput
onEndEditing={(event) => { handleChange({label: item.label, value: event.nativeEvent.text,}); }}>
{item.value}
</TextInput>
);
};
return (
<FlatList
data={items}
initialScrollIndex={0}
renderItem={({ item }) => { return <InputItem item={item} />;}}
keyExtractor={(item) => item.label}
/>
);
};
Second component
export default ListResults = ({ items }) => {
const ListResultItem = ({item}) => {
return (<Text>{item.value}</Text>);
};
return (
<FlatList
data={items}
renderItem={({item}) => { return <ListResultItem result={item} />; }}
keyExtractor={(item) => item.label}
/>
);
};
App containing the components:
export default function DetailScreen({ route, navigation }) {
const [parameters, setParameters] = React.useState(initialParameters);
const [results, setResults] = React.useState(initialResults);
const onParametersChange = (parameters) => {
setParameters(parameters);
};
const calculate = (parameters) => {
let result = [
// My values calculated
];
setResults(result);
};
React.useEffect(() => {
calculate(parameters);
}, [parameters]);
return (
<View style={Styles.container}>
<ListCoordinates
items={initialParameters}
onChange={onParametersChange} />
<ListResults
data={results} />
</View>
);
}
PS: I've tried following the answer found here, but without success: functional component rerender on state change
Any suggestion is highly appreciated ^^