【问题标题】:React useCallback called before useState issue在useState问题之前调用react useCallback
【发布时间】:2020-08-10 12:06:38
【问题描述】:

当他们按下提交时,我试图提醒用户他们根据 CheckBox 选择的选项。

但是我遇到了一个问题,当我选中 todaytomorrow 的复选框时,handleSubmit 函数之外的实际状态为 true,但在 handleSubmit 函数中,todaytomorrow 均为 false而且我不知道如何在useCallBack 钩子中渲染实际状态。因此 useCallBack 中的 todaytomorrow 将始终为 false

请有人看看我哪里出错并帮助我解决这个钩子问题。谢谢!!!

import React, { useEffect, useState, useCallback } from 'react'
import { CheckBox } from 'react-native-elements'
import { Alert } from 'react-native'

const Choose = (props) => {
    const [today, setToday] = useState(false)
    const [tommorow, setTommorow] = useState(false)

    useEffect(() => {
        props.navigation.setParams({ handleSubmit: handleSubmit })
    }, [handleSubmit])

    console.log(`today is ${today}`) // this works and is changed by the check box
    const handleSubmit = useCallback(() => {
        if (today == true){
            console.log(`today is ${today}`) // today from outise this function is never true
            
            Alert.alert('You selected today')
        }else if (tommorow == true){
            Alert.alert('You selected tommorow')
        }
    }, [today, tommorow])

    return (
        <View>
            <CheckBox
                checked={world}
                onPress={() => setToday(!today)}
                title='Today'
            />
            <CheckBox
                onPress={() => setTommorow(!tommorow)}
                title='Tommorow'
            />
        </View>
    )
}
export default ChooseToAdd

Choose.navigationOptions = () => {
    const submit = navigationData.navigation.getParam('handleSubmit')
    return {
        headerRight: () =>
            <TouchableOpacity onPress={submit}>
                <Text>Submit</Text>
            </TouchableOpacity>
    }
}

【问题讨论】:

  • 如果您重构代码以将 handleSubmit 的声明放在选择组件之外并完全放弃 useEffect 有什么不同吗?例如: const handlesubmit = (today, tomorrow) => { if (today == true){ console.log(today is ${today}) // today from outise 这个函数永远不会为真 Alert.alert('You selected today') } else if (tommorow == true){ Alert.alert('You selected tommorow') } }
  • 是的,它无法访问今天和明天的状态
  • 传递状态以便它可以访问它。
  • 请告诉我,因为我真的不知道如何将状态传递给它。我真的很感激。谢谢

标签: reactjs react-native react-hooks


【解决方案1】:

为什么不改变这个

    useEffect(() => {
        props.navigation.setParams({ handleSubmit: handleSubmit })
    }, [handleSubmit])

    console.log(`today is ${today}`) // this works and is changed by the check box
    const handleSubmit = useCallback(() => {
        if (today == true){
            console.log(`today is ${today}`) // today from outise this function is never true
            
            Alert.alert('You selected today')
        }else if (tommorow == true){
            Alert.alert('You selected tommorow')
        }
    }, [today, tommorow])

到这里

    useEffect(() => {
        const handleSubmit = () => {
            if (today == true){
                Alert.alert('You selected today')
            }else if (tommorow == true){
                Alert.alert('You selected tommorow')
            }
        }
        props.navigation.setParams({ handleSubmit: handleSubmit })
    },[today, tommorow])

【讨论】:

  • 怎么回事?你试过了吗?没有理由会导致循环。
  • 是的,我确实尝试过,然后当代码运行时,它会导致模拟器冻结,因此我认为它正在无限运行。我认为这也是因为在我的代码中的 else 语句中,我正在调度一个动作,这可能导致了循环
【解决方案2】:

我很好奇这是做什么的: 我在其他地方读到的建议之一是将函数声明移到组件范围之外,因为这使它们保持不变,而无需使用 useCallback。 我认为这将表现出相同的行为...我认为 setParams / submit 处理程序将对状态进行过时的关闭?

    import React, { useEffect, useState, useCallback } from 'react'
    import { CheckBox } from 'react-native-elements'
    import { Alert } from 'react-native'
    
    function handleSubmit(today,tomorrow) {
    return () => {
            if (today == true){
                console.log(`today is ${today}`)             
                Alert.alert('You selected today')
            }else if (tommorow == true){
                Alert.alert('You selected tommorow')
            }
    
    };
        }
    
    const Choose = (props) => {
        const [today, setToday] = useState(false)
        const [tommorow, setTommorow] = useState(false)
    
        props.navigation.setParams({ handleSubmit: handleSubmit(today,tomorrow) });

const handleTodayclicked() => {
setToday(!today);
props.navigation.setParams({ handleSubmit: handleSubmit(today,tomorrow) });
};

const handleTomorrowClicked() => {
setTommorow(!tommorow);
props.navigation.setParams({ handleSubmit: handleSubmit(today,tomorrow) });
}; 
   
        return (
            <View>
                <CheckBox
                    checked={world}
                    onPress={() => handleTodayclicked()}
                    title='Today'
                />
                <CheckBox
                    onPress={() => handleTomorrowClicked()}
                    title='Tommorow'
                />
            </View>
        )
    }
    export default ChooseToAdd
    
    Choose.navigationOptions = () => {
        const submit = navigationData.navigation.getParam('handleSubmit')
        return {
            headerRight: () =>
                <TouchableOpacity onPress={submit}>
                    <Text>Submit</Text>
                </TouchableOpacity>
        }
    }

【讨论】:

  • 我试试这个。我正在尝试在handleSubmit 函数中执行props.navigation.navigate(),所以我应该把它放在哪里(我没有在实际代码中包含navigation.navigate(),因为我认为这是必要的。)但是如果我选择handleSubmit 那么我在哪里放导航代码?
  • hmmm...像今天和明天一样将它传递给 handleSubmit()?实际上...秒 - 我有一个更新...在 onPress 处理程序中让它们调用更新 props.navigation 的函数..
猜你喜欢
  • 1970-01-01
  • 2021-08-19
  • 2021-10-07
  • 1970-01-01
  • 2021-10-02
  • 1970-01-01
  • 2020-08-04
  • 2020-12-05
  • 1970-01-01
相关资源
最近更新 更多