Więc mam to:
let total = newDealersDeckTotal.reduce(function(a, b) {
return a + b;
},
0);
console.log(total, 'tittal'); //outputs correct total
setTimeout(() => {
this.setState({dealersOverallTotal: total});
}, 10);
console.log(this.state.dealersOverallTotal, 'dealersOverallTotal1'); //outputs incorrect total
newDealersDeckTotal to tylko tablica liczb, [1, 5, 9]
np. jednak this.state.dealersOverallTotal
nie podaje prawidłowej sumy, ale total
tak jest? Ustawiłem nawet limit czasu, aby sprawdzić, czy to rozwiązało problem. jakieś oczywiste czy powinienem wysłać więcej kodu?
javascript
reactjs
state
setstate
Robak
źródło
źródło
setState
.setState
jest rzeczywiście wykonywany po zalogowaniu stanu. Myślę, że to, co zamierzałeś zrobić podczas debugowania, to umieszczenieconsole.log
części w limicie czasu i nasetState
zewnątrz.Odpowiedzi:
setState()
jest zwykle asynchroniczna, co oznacza, że w momencie określaniaconsole.log
stanu nie jest jeszcze aktualizowana. Spróbuj umieścić dziennik w wywołaniu zwrotnymsetState()
metody. Jest wykonywany po zakończeniu zmiany stanu:this.setState({ dealersOverallTotal: total }, () => { console.log(this.state.dealersOverallTotal, 'dealersOverallTotal1'); });
źródło
setState
.this.setState({someVar: newValue},function(){ console.log("force update") });
useState
haka w komponencie funkcjonalnym. UżyjuseEffect
zamiast tego, aby uzyskać efekt po renderowaniu.setState jest asynchroniczna. Możesz użyć metody wywołania zwrotnego, aby uzyskać zaktualizowany stan.
changeHandler(event) { this.setState({ yourName: event.target.value }, () => console.log(this.state.yourName)); }
źródło
Korzystanie z async / await
async changeHandler(event) { await this.setState({ yourName: event.target.value }); console.log(this.state.yourName); }
źródło
setState()
Operacja asynchroniczna , a tym samym swójconsole.log()
zostanie wykonany przedsetState()
mutuje wartości i stąd można zobaczyć wynik.Aby rozwiązać ten problem, zarejestruj wartość w funkcji wywołania zwrotnego
setState()
, na przykład:setTimeout(() => { this.setState({dealersOverallTotal: total}, function(){ console.log(this.state.dealersOverallTotal, 'dealersOverallTotal1'); }); }, 10)
źródło
W przypadku haczyków należy użyć
useEffect
haka.const [fruit, setFruit] = useState(''); setFruit('Apple'); useEffect(() => { console.log('Fruit', fruit); }, [fruit])
źródło
useEffect
działa przy każdym ponownym renderowaniu, a jeśli elementy przekazane do tablicy są zmiennymi stanu, zostaną zmienione. Więc kiedy owoc się zmieni i komponent zostanie ponownie wyrenderowany, to useEffect będzie działać.Setstate reaguje asynchronicznie, więc aby zobaczyć zaktualizowany stan w konsoli, użyj wywołania zwrotnego, jak pokazano poniżej (funkcja Callback zostanie wykonana po aktualizacji setstate)
Poniższa metoda jest „niezalecana”, ale dla zrozumienia, jeśli zmienisz stan bezpośrednio, możesz zobaczyć zaktualizowany stan w następnej linii. Powtarzam, że to „nie jest zalecane”
źródło
po prostu dodaj
componentDidUpdate(){}
metodę do swojego kodu i będzie działać. tutaj możesz sprawdzić cykl życia React Native:https://images.app.goo.gl/BVRAi4ea2P4LchqJ8
źródło
Miałem problem z kilkakrotnym ustawieniem stanu reakcji (zawsze używał stanu domyślnego). Po tym problemie z odpowiedzią / githubem zadziałał dla mnie
const [state, setState] = useState({ foo: "abc", bar: 123 }); // Do this! setState(prevState => { return { ...prevState, foo: "def" }; }); setState(prevState => { return { ...prevState, bar: 456 }; });
źródło
Miałem taką samą sytuację z jakimś zawiłym kodem i nic z istniejących sugestii nie zadziałało.
Mój problem polegał na tym, że
setState
działo się to z funkcji wywołania zwrotnego, wydanej przez jeden z komponentów. I podejrzewam, że połączenie odbywało się synchronicznie, co zapobiegałosetState
w ogóle ustawienie stanu.Po prostu mam coś takiego:
render() { <Control ref={_ => this.control = _} onChange={this.handleChange} onUpdated={this.handleUpdate} /> } handleChange() { this.control.doUpdate(); } handleUpdate() { this.setState({...}); }
Sposób miałem do „fix” było umieścić
doUpdate()
wsetTimeout
ten sposób:handleChange() { setTimeout(() => { this.control.doUpdate(); }, 10); }
Nie jest to idealne rozwiązanie, ale poza tym byłoby to znaczące refaktoryzacja.
źródło