父状态更改后反应子组件不更新
React child component don't update after parent state changed
这个问题已经被问过好几次了,但我只能找到 class 组件的答案,而不能找到功能组件的答案,我的问题对我来说似乎有点奇怪,所以我对 React 的行为为何如此感兴趣。
我想在 React Native 中创建一个计时器。
当计时器结束时,它会触发 onTimeEnd
方法,该方法会更新 App 组件的状态并触发 Timer 组件的 timeInSec
属性上的 useEffect
。
当按下 App 组件的重置按钮时,它会更新 App 组件的状态,但不会触发 useEffect
Timer 组件。我不明白为什么。
我希望您能明白我的代码的意思(我删除了我认为不会影响此代码的其他功能)。
App
分量:
import React, { useState } from 'react'
import { TouchableOpacity, StyleSheet, Text, View, TextInput } from 'react-native'
import Layout from './components/Layout'
import Timer from './components/Timer'
const App = () => {
const defaultTime = 20
const [timeLeft, setTimeLeft] = useState(defaultTime)
const onTimeEnd = () => {
setTimeLeft(defaultTime)
}
const resetTimer = () => {
setTimeLeft(defaultTime)
}
return (
<Timer
timeInSec={timeLeft}
onTimeEnd={onTimeEnd}
/>
<TouchableOpacity onPress={resetTimer}>
<Text>Reset</Text>
</TouchableOpacity>
);
}
export default App
Timer
分量:
import React, { useEffect, useState } from 'react'
import { View, Text} from 'react-native'
const Timer = (props) => {
const [timeInSec, setTimeInSec] = useState(props.timeInSec)
useEffect(() => {
const interval = setInterval(() => {
const newTime = timeInSec - 1
setTimeInSec(newTime)
if (newTime === 0) {
clearInterval(interval)
props.onTimeEnd()
}
}, 1000)
return () => clearInterval(interval)
})
useEffect(() => {
// This useEffect is triggered when the state of the App component changes from the onTimeEnd function,
// but not when it changes from the resetTimer function. Why ?
setTimeInSec(props.timeInSec)
}, [props.timeInSec])
return (
<View>
<Text>{ timeInSec }</Text>
</View>
)
}
export default Timer
问题与 useEffect 无关...组件在状态更新后没有重新呈现,因为我用相同的值更新它。所以很明显 useEffect 没有被触发。
这个问题已经被问过好几次了,但我只能找到 class 组件的答案,而不能找到功能组件的答案,我的问题对我来说似乎有点奇怪,所以我对 React 的行为为何如此感兴趣。
我想在 React Native 中创建一个计时器。
当计时器结束时,它会触发 onTimeEnd
方法,该方法会更新 App 组件的状态并触发 Timer 组件的 timeInSec
属性上的 useEffect
。
当按下 App 组件的重置按钮时,它会更新 App 组件的状态,但不会触发 useEffect
Timer 组件。我不明白为什么。
我希望您能明白我的代码的意思(我删除了我认为不会影响此代码的其他功能)。
App
分量:
import React, { useState } from 'react'
import { TouchableOpacity, StyleSheet, Text, View, TextInput } from 'react-native'
import Layout from './components/Layout'
import Timer from './components/Timer'
const App = () => {
const defaultTime = 20
const [timeLeft, setTimeLeft] = useState(defaultTime)
const onTimeEnd = () => {
setTimeLeft(defaultTime)
}
const resetTimer = () => {
setTimeLeft(defaultTime)
}
return (
<Timer
timeInSec={timeLeft}
onTimeEnd={onTimeEnd}
/>
<TouchableOpacity onPress={resetTimer}>
<Text>Reset</Text>
</TouchableOpacity>
);
}
export default App
Timer
分量:
import React, { useEffect, useState } from 'react'
import { View, Text} from 'react-native'
const Timer = (props) => {
const [timeInSec, setTimeInSec] = useState(props.timeInSec)
useEffect(() => {
const interval = setInterval(() => {
const newTime = timeInSec - 1
setTimeInSec(newTime)
if (newTime === 0) {
clearInterval(interval)
props.onTimeEnd()
}
}, 1000)
return () => clearInterval(interval)
})
useEffect(() => {
// This useEffect is triggered when the state of the App component changes from the onTimeEnd function,
// but not when it changes from the resetTimer function. Why ?
setTimeInSec(props.timeInSec)
}, [props.timeInSec])
return (
<View>
<Text>{ timeInSec }</Text>
</View>
)
}
export default Timer
问题与 useEffect 无关...组件在状态更新后没有重新呈现,因为我用相同的值更新它。所以很明显 useEffect 没有被触发。