I have a list of components in a screen. Each component makes a calculation on useEffect. I expect then to update as soon as they finish each calculation, but instead they all update after all calculations completes.
What I'm doing wrong?
Example of component:
import React, {useEffect, useState} from 'react';
import {View, Text} from 'react-native';
const Teste = () => {
const Item = props => {
const [tempo, setTempo] = useState('calculando...');
useEffect(() => {
const inicio = new Date();
const rdm = Math.random();
sleep(rdm * 1000 2000);
setTempo(`${new Date() - inicio} millisegundos`);
}, []);
const sleep = milliseconds => {
const date = Date.now();
let currentDate = null;
do {
currentDate = Date.now();
} while (currentDate - date < milliseconds);
};
return (
<View style={{marginBottom: 20}}>
<Text>Item {props.nome}</Text>
<Text>Tempo - {tempo}</Text>
</View>
);
};
return (
<View style={{padding: 40}}>
<Item nome="1" />
<Item nome="2" />
<Item nome="3" />
</View>
);
};
export default Teste;
CodePudding user response:
Two problems here...
- That
sleep
function, I literally can't even - You've defined your
Item
component inside yourTeste
component which means wheneverTeste
renders,Item
is redefined
I suggest moving Item
out of Teste
and using a promise-based sleep
const sleep = (ms) => {
let timer;
const promise = new Promise(r => {
timer = setTimeout(r, ms);
});
return [ promise, () => { clearTimeout(timer); } ];
};
const Item = ({ nome }) => {
const [tempo, setTempo] = useState('calculando...');
useEffect(() => {
const inicio = new Date();
const rdm = Math.random();
const [ delay, cancel ] = sleep(rdm * 1000 2000);
delay.then(() => {
setTempo(`${new Date() - inicio} millisegundos`);
});
return cancel; // make sure timeout is cleared on unmount
}, []);
return (
<View style={{marginBottom: 20}}>
<Text>Item {nome}</Text>
<Text>Tempo - {tempo}</Text>
</View>
);
};
const Teste = () => (
<View style={{padding: 40}}>
<Item nome="1" />
<Item nome="2" />
<Item nome="3" />
</View>
);
Here sleep()
returns both a promise that resolves once the timeout has expired as well as a function to cancel the delay if your component is unmounted.