При вводе нового значения в поле ввода стирается предыдущее. - PullRequest
1 голос
/ 17 июня 2020

С моим текущим кодом у меня есть два поля ввода и раскрывающееся меню. Когда какое-либо значение помещается в поле или изменяется, оно очищает остальные поля. Единственное, что останется неизменным - это раскрывающееся меню. У меня есть подозрения, что мои хуки useEffect могут что-то делать, но я не знаю почему. Любые предложения были бы замечательными. (FYI: storeArti c - это pu sh для firebase)

CustomScreen. js

import React, { useState } from "react";
import { StyleSheet, Text, Keyboard, View, TouchableWithoutFeedback } from "react-native";
import { Button, Input } from "react-native-elements";
import { Dropdown } from "react-native-material-dropdown";
import { storeArtic } from '../helpers/fb-settings';

const CustomScreen = ({ route, navigation }) =>{
    //create a screen with the ability to add a picture with text to the deck of artic cards
    //add check box solution for selection of word type (maybe bubbles, ask about this)
    const articDrop = [
        {value: 'CV'},
        {value: 'VC'},
        {value: 'VV'},
        {value: 'VCV'},
        {value: 'CVCV'},
        {value: 'C1V1C1V2'},
        {value: 'C1V1C2V2'},
    ];

    const [articCard, setCard] = useState({
        word: '',
        imageUrl: '',
        aType:'',
        cType: '',
        mastery: false
    })

    return(
        <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
            <View>
                <Text>Please enter the information of your custom card!</Text>
                <Input
                    placeholder="Enter valid image url"
                    value={articCard.imageUrl}
                    autoCorrect={false}
                    onChangeText={(val) => setCard({ imageUrl: val })}
                />        
                <Input
                    placeholder="Enter word or phrase"
                    value={articCard.word}
                    autoCorrect={false}
                    onChangeText={(val) => 
                        setCard({ word: val, aType: val.charAt(0).toUpperCase(), mastery: false})
                    }
                />
                <Dropdown
                    value={articCard.cType}
                    onChangeText={(text) => setCard({cType: text})}
                    label="Artic Type"
                    data={articDrop}
                />
                <Button
                //this will save the cards to the database
                    title="Save"
                    onPress={() => {
                        storeArtic({articCard})
                    }} 
                />
                <Button
                    title="Clear"
                    onPress={() => {
                        setCard({word: '', aType: '', cType: '', imageUrl: '', mastery: false});
                        navigation.navigate('Home');
                    }}
                />
            </View>
        </TouchableWithoutFeedback>
    )
}


export default CustomScreen;

HomeScreen. js

import React, { useState, useEffect } from "react";
import { StyleSheet, Text, Keyboard, TouchableOpacity, View, TouchableWithoutFeedback, Image } from "react-native";
import { Button } from "react-native-elements";
import { Feather } from "@expo/vector-icons";
import { initArticDB, setupArticListener } from '../helpers/fb-settings';


const HomeScreen = ({route, navigation}) => {
  const [ initialDeck, setInitialDeck] = useState([]);

  useEffect(() => {
    try {
      initArticDB();
    } catch (err) {
      console.log(err);
    }
    setupArticListener((items) => {
      setInitialDeck(items);
    });
  }, []);

  useEffect(() => {
    if(route.params?.articCard){
      setCard({imageUrl: state.imageUrl, word: state.word, aType: state.aType, cType: state.cType, mastery: state.mastery})
    }
  }, [route.params?.articType] );


  navigation.setOptions({
        headerRight: () => (
          <TouchableOpacity
            onPress={() =>
              navigation.navigate('Settings')
            }
          >
            <Feather
              style={styles.headerButton}
              name="settings"
              size={24}
              color="#fff"
            />
          </TouchableOpacity>
        ),
        headerLeft: () => (
          <TouchableOpacity
            onPress={() =>
              navigation.navigate('About')
            }
          >
            <Text style={styles.headerButton}> About </Text>
          </TouchableOpacity>
        ),
      });

    return(
      <TouchableWithoutFeedback onPress={Keyboard.dismiss}>
        <View style={styles.container}>
          <Text style={styles.textmenu}>Welcome to Artic Cards</Text>
          <Text style={styles.textsubmenu}>Press Start to Begin!</Text>
          <Image source={require('../assets/5-snowflake-png-image.png')}
            style={{width: 300, height: 300, alignSelf: 'center'}}/>
          <Button
            title="Start"
            style={styles.buttons}
            onPress={() => navigation.navigate('Cards',
            {passDeck: initialDeck})}
          />
          <Button
            title="Progress"
            style={styles.buttons}
            onPress={() => navigation.navigate('Progress')}
          />
          <Button
            title="Customize"
            style={styles.buttons}
            onPress={() => navigation.navigate('Customize')}
          />
        </View>
      </TouchableWithoutFeedback>
    );
};

const styles = StyleSheet.create({
  container: {
    padding: 10,
    backgroundColor: '#E8EAF6',
    flex: 1,
    justifyContent: 'center'
  },
  textmenu: {
    textAlign: 'center',
    fontSize: 30
  },
  textsubmenu:{
    textAlign: 'center',
    fontSize: 15
  },
  headerButton: {
    color: '#fff',
    fontWeight: 'bold',
    margin: 10,
  },
  buttons: {
    padding: 10,
  },
  inputError: {
    color: 'red',
  },
  input: {
    padding: 10,
  },
  resultsGrid: {
    borderColor: '#000',
    borderWidth: 1,
  },
  resultsRow: {
    flexDirection: 'row',
    borderColor: '#000',
    borderBottomWidth: 1,
  },
  resultsLabelContainer: {
    borderRightWidth: 1,
    borderRightColor: '#000',
    flex: 1,
  },
  resultsLabelText: {
    fontWeight: 'bold',
    fontSize: 20,
    padding: 10,
  },
  resultsValueText: {
    fontWeight: 'bold',
    fontSize: 20,
    flex: 1,
    padding: 10,
  },
});

export default HomeScreen;

1 Ответ

2 голосов
/ 17 июня 2020

В отличие от setState на основе классов, с функциональными компонентами, когда вы выполняете setState, он переопределяет состояние тем, что вы предоставляете внутри функции setState. Мы несем ответственность за изменение состояния (не перезапись).

Итак, если ваше состояние является объектом, используйте обратный вызов и распространите предыдущее состояние, а затем обновите новое состояние.

Как это

                <Input
                    placeholder="Enter valid image url"
                    value={articCard.imageUrl}
                    autoCorrect={false}
                    onChangeText={(val) => setCard(prev => ({ ...prev, imageUrl: val }))} //<----- like this
                /> 

Сделайте то же самое для всех ваших входных данных.

...