默认值优先

default value comes first useState

我正在使用 react-native-phone-number-input 获取用户的 phone 号码。还使用 expo location 获取用户的 isoCountryCode,然后我通过 useState 将它设置为一个变量,但是在开始时它是 null 所以在 phone 数字部分出现默认值,我怎样才能正确捕捉它?

import PhoneInput, { PhoneInputProps } from 'react-native-phone-number-input';
import * as Location from 'expo-location';
const [countryCode, setCountryCode] = useState<
    PhoneInputProps['defaultCode'] | string | null
  >();
  useEffect(() => {
    (async () => {
      const { status } = await Location.requestForegroundPermissionsAsync();
      if (status !== 'granted') {
        setCountryCode('GB');
        return;
      }
      const location = await Location.getCurrentPositionAsync({});
      // await Location.isBackgroundLocationAvailableAsync()
      await (
        await Location.reverseGeocodeAsync(location.coords)
      ).map((a) => setCountryCode(a.isoCountryCode)); <<< I catch the isoCountryCode here
    })();
  }, []);

  console.log('Country Code : ', countryCode);
...
<PhoneInput
      ref={childRef}
      value={value}
      defaultCode={countryCode ? countryCode : 'GB'} <<< It should be set here, but always default comes first
      textInputProps={{
        keyboardType: 'phone-pad',
        ...(props.textInputProps || {}),
      }}
      containerStyle={{ marginTop: 20, backgroundColor: 'transparent' }}
      countryPickerButtonStyle={styles.countryPickerButtonStyle}
      textContainerStyle={styles.textContainer}
      flagButtonStyle={{}}
      textInputStyle={{}}
      codeTextStyle={{}}
      countryPickerProps={{
        ...(props.countryPickerProps || {}),
      }}
...

和console.log输出

Country Code :  undefined
Country Code :  TR

您所在州的默认值是 undefined 并且 useEffect 中的代码是异步的。因此,预计在第一次渲染中状态的值是 undefined。在 useEffect 中设置新状态后,新的渲染周期将 运行 具有更新后的状态值。

如果你想防止这种情况发生,你可以提供一个默认值(如果我们在这里谈论位置,这可能没有多大意义)

const [countryCode, setCountryCode] = useState<
    PhoneInputProps['defaultCode'] | string | null
  >(‘SomeCode’);

或者您可以使用条件渲染来等待位置被获取,如下所示。


const [countryCode, setCountryCode] = useState<
    PhoneInputProps['defaultCode'] | string | null
  >();
  useEffect(() => {
    (async () => {
      const { status } = await Location.requestForegroundPermissionsAsync();
      if (status !== 'granted') {
        setCountryCode('GB');
        return;
      }
      const location = await Location.getCurrentPositionAsync({});
      // await Location.isBackgroundLocationAvailableAsync()
      await (
        await Location.reverseGeocodeAsync(location.coords)
      ).map((a) => setCountryCode(a.isoCountryCode)); <<< I catch the isoCountryCode here
    })();
  }, []);

if (!countryCode) {
   return null
}

// else return phone input 

return (…)