Update props from other component in react native

坚强是说给别人听的谎言 提交于 2019-12-11 15:18:44

问题


I have a Main class which I show an array to user, then in detail page user can edit each element which I'm passing using react navigation parameter. I want to edit my array in the detail class and save it using async storage.

//Main.jsimport React from 'react';
import {
    StyleSheet ,
     Text,
     View, 
     TextInput,
     ScrollView,
     TouchableOpacity,
     KeyboardAvoidingView,
     AsyncStorage
    } from 'react-native'
import Note from './Note'
import detail from './Details'
import { createStackNavigator, createAppContainer } from "react-navigation";


export default class Main extends React.Component {

  static navigationOptions = {
    title: 'To do list',
    headerStyle: {
      backgroundColor: '#f4511e',
    },
  };

  constructor(props){
    super(props);
    this.state = {
      noteArray: [],
      noteText: '',
      dueDate: ''
    };
  }

  async saveUserTasks(value) {
    try {
      await AsyncStorage.setItem('@MySuperStore:userTask',JSON.stringify(value));
    } catch (error) {
      console.log("Error saving data" + error);
    }
  }
   getUserTasks = async() =>{
    try {
      const value = await AsyncStorage.getItem('@MySuperStore:userTask');
      if (value !== null){
        this.setState({ noteArray: JSON.parse(value)});
      }
    } catch (error) {
      console.log("Error retrieving data" + error);
    }
  }

render() {
  this.getUserTasks()
    let notes = this.state.noteArray.map((val,key) => {
      return <Note key={key} keyval={key} val={val}
      deleteMethod={ () => this.deleteNote(key)}
      goToDetailPage= {() => this.goToNoteDetail(key)}
       />
    });
    const { navigation } = this.props;
    return(
      <KeyboardAvoidingView behavior='padding' style={styles.keyboard}>
        <View style={styles.container}>
            <ScrollView style={styles.scrollContainer}>
                {notes}
            </ScrollView>
            <View style={styles.footer}>
                <TextInput
                onChangeText={(noteText) => this.setState({noteText})}
                style={styles.textInput}
                placeholder='What is your next Task?'
                placeholderTextColor='white'
                underlineColorAndroid = 'transparent'
                >
                </TextInput>
            </View>
            <TouchableOpacity onPress={this.addNote.bind(this)} style={styles.addButton}>
                <Text style={styles.addButtonText}> + </Text>
            </TouchableOpacity>
        </View>
   </KeyboardAvoidingView>
      );
    }
    addNote(){
      if (this.state.noteText){
        var d = new Date();
        this.state.noteArray.push({ 
        'creationDate': d.getFullYear() + "/" + (d.getMonth()+1) + "/" + d.getDay(), 'taskName': this.state.noteText,'dueDate':'YYYY/MM/DD'
        });
        this.setState({noteArray:this.state.noteArray})
        this.setState({noteText: ''});
        this.saveUserTasks(this.state.noteArray) 
      }
    }
    deleteNote(key){
      this.state.noteArray.splice(key,1);
      this.setState({noteArray: this.state.noteArray})
      this.saveUserTasks(this.state.noteArray)       
    }
    goToNoteDetail=(key)=>{   
      this.props.navigation.navigate('DetailsScreen', {
        selectedTask: this.state.noteArray[key],
      });
    }     
}

in detail view I have this method which is similar to add note in main class:

export default class Details extends React.Component {
  render() {
    const { navigation } = this.props;
    const selectedTask = navigation.getParam('selectedTask', 'task');
    return(
     <View key={this.props.keyval} style={styles.container}>
      <TouchableOpacity onPress={this.saveEdit.bind(this)} style={styles.saveButton}>
                <Text style={styles.saveButtonText}> save </Text>
      </TouchableOpacity>
    </View>
    );
  }
  saveEdit(){

    let selectedItem = { 'creationDate': selectedTask['creationDate'], 
    'taskName': selectedTask['taskName'],
    'dueDate': this.state.dueData}


this.props.navigation.state.params.saveEdit(selectedItem)
      }
    }

How can I change my props in any component?


回答1:


First of all you shouldn't call this.getUserTasks() in the render method because the function has this.setState which is bad and could end in a endless loop I guess or at least effect in worse performance. You could instead call it in componentDidMount:

componentDidMount = () => {
    this.getUserTasks();
}

Or alternatively call already in constructor but I prefer the first option:

constructor(props){
  super(props);
  this.state = {
    noteArray: [],
    noteText: '',
    dueDate: ''
  };

  this.getUserTasks()
}

this.props.noteArray.push({.. is probably undefined because you aren't passing it down any where. (Didn't see any reference in your snippet). I guess I would implement the saveEdit function in the Main.js component and simply pass it down to the navigation route and call the function in Details component by accessing the navigation state props:

Update

  goToNoteDetail=(key)=>{   
    this.props.navigation.navigate('DetailsScreen', {
      // selectedTask: this.state.noteArray[key],
      selectedItem: key,
      saveEdit: this.saveEdit
    });
  }     

  saveEdit(selectedItem){
    const selectedTask = this.state.noteArray[selectedItem]
    this.state.noteArray.push({ 
      'creationDate': selectedTask['creationDate'], 
      'taskName': selectedTask['taskName'],
      'dueDate': this.state.dueData
    });
    this.setState({noteArray:this.state.noteArray})
    this.setState({dueData: 'YYYY/MM/DD'});
    this.saveUserTasks(this.state.noteArray) 
  }

And then call saveEdit in Details Component:

saveSelectedItem = () => {
  const { navigation } = this.props.navigation;
  const {selectedItem, saveEdit} = navigation.state && navigation.state.params;
  saveEdit(selectedItem)
}


来源:https://stackoverflow.com/questions/56396525/update-props-from-other-component-in-react-native

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!