Обновить реквизит из другого компонента в реагировать родной - PullRequest
0 голосов
/ 31 мая 2019

У меня есть класс Main, который я показываю массиву пользователю, затем пользователь страницы может подробно редактировать каждый элемент, который я передаю, используя параметр реакции навигации.Я хочу отредактировать свой массив в классе сведений и сохранить его с помощью асинхронного хранилища.

//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],
      });
    }     
}

в подробном представлении У меня есть этот метод, аналогичный добавлению примечания в основной класс:

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)
      }
    }

Как мне поменять реквизит в любом компоненте?

1 Ответ

1 голос
/ 31 мая 2019

Прежде всего, вы не должны вызывать this.getUserTasks () в методе рендеринга, потому что функция имеет this.setState, который является плохим и может закончиться бесконечным циклом, я думаю или, по крайней мере, повлиять на худшую производительность. Вместо этого вы можете вызвать его в componentDidMount:

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

Или, альтернативно, вызовите уже в конструкторе, но я предпочитаю первый вариант:

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

  this.getUserTasks()
}

this.props.noteArray.push ({.., вероятно, не определено, потому что вы не передаете его где-либо. (Я не видел ссылки в вашем фрагменте). Думаю, я бы реализовал функцию saveEdit в Компонент Main.js и просто передайте его по маршруту навигации и вызовите функцию в компоненте Details, открыв реквизиты состояния навигации:

Обновление

  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) 
  }

А затем вызвать saveEdit в компоненте Details:

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