父状态更改后反应子组件不更新

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 没有被触发。