Rohit Girdhar
Rohit Girdhar

Reputation: 353

Add data in React Native and Save the State

I'm building a basic React Native application where the user enters his name in a TextInput and on button press his name along with his image is added to a ScrollView in another View. Images are stored and named in accord with the name of the person. Example - Name: 'ABC', the image fetched from assets will be 'ABC.jpg'.

I'm able to do this for one person, but every time I add a new entry the previous one gets overwritten. How can I retain the previous entry yet add another entry?

Home

import React, {Component} from 'react';
import { StyleSheet, Text, View, Image, ScrollView, Button, TouchableWithoutFeedback, TextInput} from 'react-native';
import { createStackNavigator } from 'react-navigation';

class HomeScreen extends React.Component {
    render() {
        const { navigation } = this.props;
        const name0 = navigation.getParam('name0', 'NO-ID');
        return (
            <View style={styles.container}>
              <ScrollView vertical={true} contentContainerStyle={{flexGrow: 1}}>
              <Text style={styles.category}>Category 1</Text>


              <ScrollView horizontal={true} showsHorizontalScrollIndicator={false}>
                  <TouchableWithoutFeedback onPress={() => {
                        this.props.navigation.navigate('Details', {
                        name: name0,
                        intro: 'lorem ipsum',
                        detail1: 'XYZ',
                        detail2: 'ABC',
                        });
                  }}>
                  <View style={styles.view}>
                      <Image source={require('./assets/rohit.jpg')} style={styles.image}></Image>
                      <Text style={styles.text}>{name0}</Text>
                  </View>
                  </TouchableWithoutFeedback>
                  </ScrollView>



              </ScrollView>
            </View>
        )
    }
}

Add Data

class AddData extends React.Component {
    constructor(props) {
    super(props);
    this.state = { text: '' };
}
  render() {
      function onPressLearnMore() {
          alert('Hi')
      }
    return (
      <View style={{flex: 1, flexDirection: 'column', justifyContent:'center', alignItems: 'center'}}>
          <TextInput
          style={{height: 40,width:200}}
          onChangeText={(text) => this.setState({input: text})}
        />
        <Button
        onPress={() => {
              this.props.navigation.navigate('Home', {
              name0: this.state.input
              });
        }}
        title="Pass Data"
        />

      </View>
    );
  }
}

Navigator

const RootStack = createStackNavigator(
  {
    Home: HomeScreen,
    Details: DetailsScreen,
    Data: AddData
  },
  {
    initialRouteName: 'Data',
  }
);

export default class App extends React.Component {
  render() {
    return <RootStack />;
  }
}

Screen 1 Screen 2

Upvotes: 3

Views: 5173

Answers (1)

Gavin Thomas
Gavin Thomas

Reputation: 1867

Because you aren't saving your data from the user input anywhere, simply passing it back to home, it is getting overwritten and as your code sits, it is working! ;)

To simply put a bandaid on what you're doing, because this method of passing data is slightly taboo.. and you cannot achieve what you're asking without some sort of state persistence like AsyncStorage, or... to not have two screens. Because everytime React re-renders your screen any data that was in your state object disappears...

Inside your home component, on did mount you could store user input to state as objects inside an array. IN the below example I am using the user data you are sending back to home, however this would need to be data retrieved from some sort of persistence.

class HomeScreen extends React.Component {
constructor(props) {
super(props)
this.state = {
  usersArray: []
}
}
componentDidMount() {
  let userInfo = this.props.navigation.getParam('name0', 'NO-ID');
  userInfo !== undefined ? this.setState({usersArray: 
[...this.state.usersArray, userInfo]}) : console.log('NO USER DATA to add')
}
render() {
    const { navigation } = this.props;
    const name0 = navigation.getParam('name0', 'NO-ID');
    return (
        <View style={styles.container}>
          <ScrollView vertical={true} contentContainerStyle={{flexGrow: 1}}>
          <Text style={styles.category}>Category 1</Text>


          <ScrollView horizontal={true} showsHorizontalScrollIndicator={false}>
              <TouchableWithoutFeedback onPress={() => {
                    this.props.navigation.navigate('Details', {
                    name: name0,
                    intro: 'lorem ipsum',
                    detail1: 'XYZ',
                    detail2: 'ABC',
                    });
              }}>
              <View style={styles.view}>
                  <Image source={require('./assets/rohit.jpg')} style={styles.image}></Image>
                  {/* <Text style={styles.text}>{name0}</Text> */}
                 { this.state.usersArray.map((ele, index) => {
                    return <Text key={index} style={styles.text}>{ele.name}</Text>

                  })}
              </View>
              </TouchableWithoutFeedback>
              </ScrollView>



          </ScrollView>
        </View>
    )
  }
}

Please keep in mind you may need to change your user data to be objects for this rest and spreading to work.

Upvotes: 2

Related Questions