【问题标题】:React native hook state doesn't update inside a functionReact 本机钩子状态不会在函数内更新
【发布时间】:2020-08-19 13:59:15
【问题描述】:


如果我的 list.lenght 大于 10,我的任务是导航到另一个屏幕。 我的 list 已使用 hooks e redux 正确更新。

我有 ActionSheetIOS.showActionSheetWithOptions,当我按“go”时,我想检查 list.lenght 并检查它是否 > 10。

状态 (list.lenght) 正确更新,但不在我的函数中。在我的函数中,状态是第一个状态。

我尝试将我的函数放在useEffect中,我认为更新列表时值会更新,但事实并非如此。

这是我的代码

export default function CustomersList(props) {

    const userId = useSelector(state => state.loggedReducer.userId);
    const customers = useSelector(state => state.customers.customers);

    const dispatch = useDispatch();

    const [refreshing, setRefreshing] = React.useState(false);
    const onRefresh = React.useCallback(() => {
        dispatch(fetchCustomers(userId));
    }, []);

    /**
     * Add Right icon on header
     * */
    React.useLayoutEffect(() => {
        props.navigation.setOptions({
            headerRight: () => (<Ionicons name="ios-more" size={24} color="white" onPress={() => {onPress()}} style={{marginRight: 20}}/>),
        });
    }, [props.navigation]);

    let clickGo;

    const onPress = () => {
        console.log("rendered");
        ActionSheetIOS.showActionSheetWithOptions(
            {
                options: ["Cancel", "go"],
                cancelButtonIndex: 0,
            },
            buttonIndex => {
                switch (buttonIndex) {
                    case 0: // cancel Action
                        break;
                    case 1: // Go
                        clickGo();
                        break;
                }
            }
        );
    }

    useLayoutEffect(() => {
        console.log(customers.length); // updated state

        clickGo = () => {
            console.log("state", customers.length); // old state :(
            if(customers.length < 10){
                props.navigation.navigate("NewCustomer");
            }else{
                alert("upgrade to premium")
            }
        }
    }, [customers])

}

【问题讨论】:

  • 你为什么使用useLayoutEffect
  • 这是我最后一次尝试,在我使用 useEffect 之前。但结果是一样的。我的状态没有更新

标签: reactjs react-native react-hooks react-native-ios use-effect


【解决方案1】:

设置clickGo 的逻辑有点偏离 - 最简单的解决方法是删除此逻辑并将其全部放入onPress

const onPress = () => {
    console.log("rendered");
    ActionSheetIOS.showActionSheetWithOptions(
        {
            options: ["Cancel", "go"],
            cancelButtonIndex: 0,
        },
        buttonIndex => {
            switch (buttonIndex) {
                case 0: // cancel Action
                    break;
                case 1: // Go
                    if (customers.length < 10) {
                        props.navigation.navigate("NewCustomer");
                    } else {
                        alert("upgrade to premium")
                    }
                    break;
            }
        }
    );
}

另外 - 确保将依赖项添加到 onRefresh 中的数组!

【讨论】:

  • 我先尝试了这个,可惜放了一个console.log,我意识到这个函数里面的值(customers.lenght)是第一次加载页面时的初始值。而且它不会随列表更新,但它始终保持不变:(
【解决方案2】:

我找到了解决方案,我已将所有脚本放入这样的 useEffect 中。

useEffect(() => {

    console.log(customers.length);

    props.navigation.setOptions({
        headerRight: () => (<Ionicons name="ios-more" size={24} color="white" onPress={() => {onPress()}} style={{marginRight: 20}}/>),
    });

    const onPress = () => {
        ActionSheetIOS.showActionSheetWithOptions(
            {
                options: ["Cancel", strings.createNewCustomer, strings.connectWithCustomer],
                cancelButtonIndex: 0,
            },
            buttonIndex => {
                switch (buttonIndex) {
                    case 0: // cancel Action
                        break;
                    case 1: // Create new Client Action
                        if(!premium){
                            if(customers.length < 10){
                                props.navigation.navigate("NewCustomer");
                            }else {
                                Alert.alert(strings.upgradeToPremium)
                            }
                        }else {
                            props.navigation.navigate("NewCustomer");
                        }
                        break;
                    case 2: // Connect
                        if(!premium){
                            if(customers.length < 10){
                                openConnectModal();
                            }else {
                                Alert.alert(strings.upgradeToPremium)
                            }
                        }else {
                            openConnectModal();
                        }
                        break;
                }
            }
        );
    }


}, [customers])

【讨论】:

    猜你喜欢
    • 2019-10-29
    • 1970-01-01
    • 2021-05-24
    • 1970-01-01
    • 1970-01-01
    • 2021-08-24
    • 1970-01-01
    • 1970-01-01
    • 2020-10-13
    相关资源
    最近更新 更多