#javascript #react-native
Вопрос:
Итак, у меня есть этот код здесь. Я не знаю, связано ли это с тем, как я его структурировал, но изменение состояния с помощью функции «установить» не изменяет состояние до тех пор, пока я снова не изменю запись. Так, например, я введу текст, а затем нажму «опубликовать», который должен обновить состояние, когда консоль.предупредите, что отпечатки ничего не печатают. Затем я снова меняю текст и нажимаю «Отправить» и «консоль».предупреждение выведет то, что было там до моего последнего изменения.
import React, {useState, createRef} from 'react';
import LinearGradient from 'react-native-linear-gradient';
import {
StyleSheet,
TextInput,
View,
Text,
ScrollView,
Keyboard,
Button,
TouchableOpacity,
KeyboardAvoidingView,
} from 'react-native';
import DateTimePickerModal from 'react-native-modal-datetime-picker';
import Loader from '../components/Loader';
const GoalRegistrationScreen = ({navigation}) => {
const [isDatePickerVisible, setDatePickerVisibility] = useState(false);
const [goalText, setGoal] = useState('');
const [durationText, setDuration] = useState('');
const [descriptionText, setDescription] = useState('');
const [loading, setLoading] = useState(false);
const [errortext, setErrortext] = useState('');
const durationInputRef = createRef();
const descriptionInputRef = createRef();
function showDatePicker() {
setDatePickerVisibility(true);
}
function hideDatePicker() {
setDatePickerVisibility(false);
}
function handleConfirm(date) {
hideDatePicker();
console.warn(date);
}
function onButtonClick() {
// console.warn(goalText)
console.warn(descriptionText);
}
React.useLayoutEffect(() => {
navigation.setOptions({
title: 'Create Goal',
headerTitleAlign: 'center',
headerRight: () => (
<TouchableOpacity
style={styles.addButtonStyle}
activeOpacity={0.5}
onPress={onButtonClick}>
<LinearGradient
colors={['#FBE049', '#4964FB']}
style={styles.linearGradient}
start={{x: 0, y: 0}}
end={{x: 1, y: 1}}>
<Text style={styles.buttonTextStyle}>Post</Text>
</LinearGradient>
</TouchableOpacity>
),
});
}, [navigation]);
return (
<View style={styles.mainBody}>
<Loader loading={loading} />
<ScrollView keyboardShouldPersistTaps="handled">
<View>
<KeyboardAvoidingView enabled>
<View style={styles.SectionStyle}>
<TextInput
style={styles.inputStyle}
onChangeText={goal => setGoal(goal)}
placeholder="What do I want to accomplish?"
placeholderTextColor="#8b9cb5"
autoCapitalize="none"
returnKeyType="next"
onSubmitEditing={() =>
durationInputRef.current amp;amp; durationInputRef.current.focus()
}
underlineColorAndroid="#f000"
blurOnSubmit={false}
/>
</View>
<View style={styles.SectionStyle}>
<Button title="Show Date Picker" onPress={showDatePicker} />
<DateTimePickerModal
isVisible={isDatePickerVisible}
mode="date"
onConfirm={handleConfirm}
onCancel={hideDatePicker}
minimumDate={new Date()}
/>
{/* <TextInput
style={styles.inputStyle}
onChangeText={duration => setDuration(duration)}
placeholder="Duration of Goal"
placeholderTextColor="#8b9cb5"
keyboardType="default"
ref={durationInputRef}
onSubmitEditing={() =>
descriptionInputRef.current amp;amp;
descriptionInputRef.current.focus()
}
blurOnSubmit={false}
underlineColorAndroid="#f000"
returnKeyType="next"
/> */}
</View>
<View style={styles.SectionStyle}>
<TextInput
style={styles.accomplishmentTextStyle}
onChangeText={description => setDescription(description)}
placeholder="How can I accomplish this goal?"
placeholderTextColor="#8b9cb5"
keyboardType="default"
ref={descriptionInputRef}
onSubmitEditing={Keyboard.dismiss}
blurOnSubmit={false}
underlineColorAndroid="#f000"
returnKeyType="next"
/>
</View>
{errortext != '' ? (
<Text style={styles.errorTextStyle}>{errortext}</Text>
) : null}
</KeyboardAvoidingView>
</View>
</ScrollView>
</View>
);
};
export default GoalRegistrationScreen;
const styles = StyleSheet.create({
mainBody: {
flex: 1,
justifyContent: 'center',
backgroundColor: '#FFFFFF',
alignContent: 'center',
},
SectionStyle: {
flexDirection: 'row',
marginLeft: 35,
marginRight: 35,
margin: 10,
},
buttonTextStyle: {
color: '#000000',
paddingVertical: 10,
fontSize: 16,
paddingLeft: 15,
paddingRight: 15,
borderRadius: 32,
borderColor: '#000000',
},
inputStyle: {
flex: 1,
color: 'black',
paddingLeft: 15,
paddingRight: 15,
borderWidth: 1,
borderRadius: 30,
borderColor: '#000000',
},
accomplishmentTextStyle: {
flex: 1,
color: 'black',
paddingLeft: 15,
paddingRight: 15,
borderWidth: 1,
borderRadius: 30,
borderColor: '#000000',
height: 150,
textAlignVertical: 'top',
},
addButtonStyle: {
paddingRight: 20,
},
linearGradient: {
borderRadius: 32,
},
errorTextStyle: {
color: 'red',
textAlign: 'center',
fontSize: 14,
},
});
Вот пример, у меня был «testdsdd» в описании и обновлен до «test», функция onChangeText должна была автоматически изменить его на «test», но этого не произошло. Это происходит для всех состояний от текста цели, текста описания до даты установки.
Ответ №1:
Попробуйте сменить TextInput
onChangeText
реквизит на onChange
такой же:
onChangeText={ handleInputChange }
а затем обработайте новый ввод в handleInputChange
:
const handleInputChange = useCallback((ev) => {
const input = ev.nativeEvent.text;
// you can also do error checking here.
setDescription(input);
}, [formatMessage]);
Я всегда предлагаю использовать подобный шаблон, потому что он позволяет проверять наличие ошибок или вызывать другие методы (например, автоматический поиск).
На самом деле, я предлагаю использовать handleInputChange
для проверки ошибок и только установить новое состояние для ввода текста на an onEndEditing
.