【发布时间】:2021-12-25 14:48:56
【问题描述】:
所以我对 React native 很陌生,我正在对现有应用程序进行更新。我有两个下拉列表:一个国家下拉列表和一个城市下拉列表(这些最初是文本字段)。设置国家/地区后,城市下拉列表将从 JSON 文件填充。所有这些都可以正常工作,除非您更改国家/地区时不会立即填充城市列表。如果您设置国家两次 - 它会设置上一次选择的城市。
这是页面组件中的相关代码:
[imports all in place]
const countries2 = require('../../common/constants/countries2.json');
const cities = require('../../common/constants/cities.json');
const validator = {
city: {
required: true,
string: true,
},
country: {
required: true,
string: true,
},
};
const RegistrationAddress = ({ route }) => {
const navigation = useNavigation();
const { personalDetails, socialRegistration } = route.params || {};
const [updateUser] = useMutation(UPDATE_PROFILE, {
fetchPolicy: 'no-cache',
});
const [state, setState] = useState({
city: '',
country: '',
personalDetails: personalDetails,
});
const [errors, setErrors] = useState({});
const [filteredCities, setCities] = useState([]);
const onChange = (field, val) => {
if (field === 'country') {
updateCityPicker();
}
const newState = { ...state, [field]: val };
setState(newState);
const err = validate(newState, validator);
if (err) {
setErrors(err);
} else {
setErrors({});
}
};
useEffect(() => {
const err = validate({}, validator);
setErrors(err);
getUserAddressDetails();
}, []);
const getUserAddressDetails = async () => {
const userAddressDetail = await AsyncStorage.getItem('userAddressDetails');
const userAddressDetails = JSON.parse(userAddressDetail);
const userAddressDetailsState = {
...state,
city: userAddressDetails.city || '',
country: userAddressDetails.country || '',
};
setState(userAddressDetailsState);
const err = validate(userAddressDetailsState, validator);
if (err) {
setErrors(err);
} else {
setErrors({});
}
};
const updateCityPicker = () => {
const suggestions = cities.filter((el) => {
var s = el[country];
return s;
});
var list = [];
suggestions.forEach((element) => {
element[country].forEach((cl) => {
var obj = {};
obj['label'] = cl;
obj['value'] = cl;
list.push(obj);
});
});
setCities(list);
};
const { city, country } = state;
const navigateToRegistrationConfirmDetails = () => {
if (socialRegistration) {
updateUser({
variables: {
data: {
city,
country,
},
},
}).then(async () => {
await AsyncStorage.removeItem('userBasicDetails');
await AsyncStorage.removeItem('userAddressDetails');
navigation.navigate('QuestionnaireIntroduction');
});
} else {
navigation.navigate('RegistrationConfirmDetails', { userDetails: state });
}
};
return (
<ImageBackground style={styles.imageBackground}>
<View style={styles.regStepView}>
<Text style={styles.regStep}>
Address
<Text style={styles.oneOutOfThree}> - 3/3</Text>
</Text>
</View>
<ScrollView showsVerticalScrollIndicator={false}>
<KeyboardAvoidingView style={styles.inputsView}>
<Dropdown
mainContainerStyle={{
width: '100%',
backgroundColor: 'white',
marginTop: 5,
}}
textStyle={{ fontSize: verticalScale(14) }}
value={country}
onValueChange={(val) => onChange('country', val)}
testID="countryID"
placeholder="eg. United Kingdom"
items={countries2}
checkDropdownErrors={false}
error={errors.accountCurrency && errors.accountCurrency[0]}
showDropdownError={''}
title="Which country do you currently live in?"
/>
<Dropdown
mainContainerStyle={{
width: '100%',
backgroundColor: 'white',
marginTop: 5,
}}
textStyle={{ fontSize: verticalScale(14) }}
value={city}
onValueChange={(val) => onChange('city', val)}
testID="cityID"
placeholder="eg. London"
items={filteredCities}
checkDropdownErrors={false}
error={errors.city && errors.city[0]}
showDropdownError={''}
title="Which city do you currently live in?"
/>
</KeyboardAvoidingView>
</ScrollView>
<View>
<Button
disabled={Object.keys(errors).length}
styleContainer={{ marginBottom: scale(24) }}
title="Next"
onPressFunc={async () => {
await AsyncStorage.setItem(
'userAddressDetails',
JSON.stringify(state),
)
.then(() => navigateToRegistrationConfirmDetails())
.catch((err) => console.log({ err }));
}}
/>
</View>
</ImageBackground>
);
};
export default RegistrationAddress;
我还收到有关从另一个组件中设置组件状态的警告,这是可以理解的,但我不知道解决方案。
任何帮助将不胜感激。抱歉,如果这是一个现有问题 - 其他答案对我来说不太适用。
【问题讨论】:
标签: javascript android react-native