Собственное состояние React не обновляется даже с набором функций «onChange»

#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 .