-2

我是 react-native 的新手,我正在开发一个应用程序。

下面的代码是一个简单的 react-native 应用程序,它有一个带有自定义事件的自定义组件。

但问题是第一次单击组件时变量状态没有更新。但是当我点击第二个项目时,变量的状态被更新了。

请在下面找到代码和屏幕截图。

应用程序.js

import React, {useState} from 'react';
import { Text, SafeAreaView, ToastAndroid } from 'react-native';
import Dropdown from './components/dropdown';

const app = () => {
    const [ itemData, setItemData ] = useState('');

    return (
        <SafeAreaView style={{ margin: 50 }}>
            <Dropdown 
              onPressItems={(item) => {
                  ToastAndroid.show('item: ' + item, ToastAndroid.LONG)
                  setItemData(item)
                  ToastAndroid.show('setItem: ' + itemData, ToastAndroid.LONG)
              }}/>
        </SafeAreaView>
    );
}

export default app;

Dropdown.js

import React, { useState } from 'react';
import { TouchableOpacity, Text } from 'react-native';

const Dropdown = (props) => {
    return (
        <TouchableOpacity onPress={() => { props.onPressItems('this is sample data') }}>
            <Text>Sample Text</Text>
        </TouchableOpacity>
    );
} 

export default Dropdown;

截屏 在此处输入图像描述

代码: https ://snack.expo.dev/@likithsai/custom-component

请在这个问题上帮助我。谢谢。

4

2 回答 2

1

useState()钩子异步改变状态。所以你不能确保调用setItemData()函数后状态会立即改变。

每当状态发生变化时,尝试useEffect运行副作用。

useEffect(() => {
  ToastAndroid.show("setItem: " + itemData, ToastAndroid.LONG);
}, [itemData]);

但是,此代码将显示组件安装上的 toast。为了防止它尝试这样的事情:

const isInitialMount = useRef(true);

useEffect(() => {
  if (isInitialMount.current) {
    isInitialMount.current = false;
  } else {
    ToastAndroid.show("setItem: " + itemData, ToastAndroid.LONG);
  }
}, [itemData]);
于 2022-01-19T15:26:24.853 回答
0

您的代码按预期工作。用于监视状态更新的钩子之一是useEffect. 您可以将其添加到您的代码中,并查看它是否正常工作:

const app = () => {
    const [ itemData, setItemData ] = useState('');

    React.useEffect(() => {
      console.log('updated itemData:', itemData)
    }, [itemData])

    return (
        <SafeAreaView style={{ margin: 50 }}>
            <Dropdown 
              onPressItems={(item) => {
                  ToastAndroid.show('item: ' + item, ToastAndroid.LONG)
                  setItemData(item)
                  ToastAndroid.show('setItem: ' + itemData, ToastAndroid.LONG)
              }}/>
        </SafeAreaView>
    );
}

您需要考虑到useState更新是异步的,这意味着更改不会立即反映。

于 2022-01-19T15:29:01.307 回答