用另一个组件的道具打开一个组件

时间:2018-05-27 13:53:20

标签: javascript reactjs react-native

我正在尝试制作一个简单的笔记应用。我在touchableOpacity标签和onPress中列出了备注,我想在另一个组件中打开单击的备注。这是我遇到麻烦的地方。这里有一些代码供您理解结构。我尝试过如下,但我无法将任何信息传递给其他组件。

这是我用于定义新笔记或显示现有笔记的newNote组件。

import React from 'react';
import {ScrollView, View, StyleSheet,Text, TextInput, Button,
TouchableOpacity} from 'react-native';

const newNote = (props) => {

return (
    <View style={{alignItems: 'center'}} >
        <View style={styles.newNoteContainer}>
            <TextInput style={styles.txtTopic}
            placeholder = {'Topic'}
            value = {props.updatedNote}
            onChangeText= {props.onNewNoteHeaderChange}
            />
            <TextInput style={styles.txtNote}
            placeholder='Write your note here...' 
            onChangeText={props.onNewNoteSubChange} 
            multiline= {true}/>
        </View>
        <View style = {{
            height: 35,
            flexDirection: 'row',
            justifyContent:'space-evenly',
            alignItems: 'center',
            width:'100%',
        }}>
            <TouchableOpacity
            style={{borderRightWidth: 1,
                borderColor:'#bbb',
                flex:1,
            }}
            >
                <Button title = {'SAVE'} onPress = {props.saveNote}/>
            </TouchableOpacity>
            <TouchableOpacity
            style={{
                flex:1,
            }} >
                <Button title = 'CANCEL' onPress = {props.cancelNote}/>
            </TouchableOpacity>
        </View>
    </View>
)
}

const styles = StyleSheet.create({
    txtTopic:{
        fontFamily:'Cochin',
        fontSize: 28,
        fontWeight: 'bold',
        borderBottomWidth: 1,
        borderBottomColor: '#bbb',
        height: 50,    
    },
    txtNote:{
        fontFamily:'Cochin',
        fontSize:18,
        height:'100%',
    },
    newNoteContainer:{
        borderWidth: 1,
        borderColor: '#bbb',
        width: '100%',
        height: '88%'
    }
})

export default newNote;

我正在管理此组件对App.js状态的可见性。当我点击加号按钮时,我将state.addNote更改为true并隐藏记事列表并显示newNote组件。

这是我的App.js。

import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import HeaderField from './components/headerField';
import NoteItem from './components/noteItem';
import NoteContainer from './components/noteContainer';
import AddNote from './components/addNote';
import NewNote from './components/newNote';

export default class App extends React.Component {
  state = {
    newNote: false,
    newNote1: 1,
    updatedNote:'a',
    isUpdate:false,
    newNoteHeader:'',
    newNoteSub: '',
    noteList:[]
  }



  toMainMenu = () => {
    this.setState({
      newNote: false,
      newNoteHeader:'',
      newNoteSub: ''
    })
  }

  addNewNote = () =>{
    currentState = this.state.newNote;
    this.setState({
      newNote: !currentState
    })
  }

  onNewNoteHeaderChange = (text) =>{
    this.setState({
      newNoteHeader: text
    })
  }

  onNewNoteSubChange = (text) => {
    this.setState({
      newNoteSub: text
    })
  }
  fetchNoteList = () => {
    fetch('https://shared-places-1526811885396.firebaseio.com/notes.json')
    .then(res => res.json())
    .then(parsedRes => {
      const notesArray = [];
      for(key in parsedRes){
        notesArray.push({
          Header: parsedRes[key].Header,
          Explanation: parsedRes[key].Explanation,
          Date: parsedRes[key].Date,
          id: key
        })
      }
      this.setState({
        noteList: notesArray,
        newNote: false
      })
    })
  }
  saveNote = () => {
    fetch('https://shared-places-1526811885396.firebaseio.com/notes.json',{
      method:'POST',
      body: JSON.stringify({
          Header: this.state.newNoteHeader,
          Explanation: this.state.newNoteSub,
          Date: new Date(),
      })
    })
    .then(res => console.log(res))
    .catch(err => console.log(err))
    currentState = this.state.newNote;
    this.fetchNoteList();
  }  

  openNote = (e) => {
    this.setState({
      newNote: true,
      newNote1:0,
      updatedNote: e.date
    })
  }

  cancelNote = () => {
    currentState = this.state.newNote;
    this.setState({
      newNote: !currentState,
      newNoteHeader:'',
      newNoteSub: ''
    })
  }

  componentWillMount = () => {
    this.fetchNoteList();
  }

  render() {
    return (
      <View style={styles.container}>
        <HeaderField toMainMenu = {this.toMainMenu}/>
        {this.state.newNote ? 
        <NewNote saveNote={this.saveNote} 
          cancelNote={this.cancelNote} 
          onNewNoteHeaderChange = {this.onNewNoteHeaderChange}
          onNewNoteSubChange={this.onNewNoteSubChange} 
          isUpdate={this.state.isUpdate}
          updatedNote={this.state.updatedNote}
           /> : 
          <NoteContainer noteList={this.state.noteList} 
            openNote={this.openNote}/>}
        {!this.state.newNote && <AddNote addNewNote = {this.addNewNote}
        />}
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex:1,
    flexDirection: 'column',
    backgroundColor: '#eee',
    justifyContent: 'flex-start'
  },
});

所以在这里我试图将openNote函数传递给grand child组件。首先我将其传递给NoteContainer,然后在NoteContainer中将其传递给NoteItem

这是NoteContainer。

const noteContainer = (props) => {
    noteList = props.noteList.map((note,i) =>(
        <NoteItem header={note.Header}
            explanation = {note.Explanation}
            date = {note.Date}
            key= {i}
            openNote = {props.openNote}
            />
    ))

    return (
        <ScrollView>
            {noteList ? noteList : 
            <Text>{'You don\'t have a note yet.'
            + '\n' + 'Click plus button to add one.'
                }
            </Text>}
        </ScrollView>
    )
}

这是NoteItem。

const noteItem = (props) => {
    let date = props.date.substring(0,10);
    let explanation = props.explanation.substring(0,45) + '...';

    return(
        <TouchableOpacity style = {styles.noteContainer}
            onPress = {props.openNote}
        >
            <View style={styles.noteIdentifier} />
            <View style={styles.notePreviewContainer} >
                <Text style ={styles.noteHeader} >{props.header}</Text>
                <Text style ={styles.notePreviewLine} >{explanation}</Text>
            </View>
            <Text style ={styles.notePreviewLine}>{date}</Text>
        </TouchableOpacity>
    )
}

打开笔记实际上正在工作,我可以打开newNote组件。但我需要检索点击的noteItem信息。至少是键或订单号,以便我可以从具有noteList数组的状态中检索数据。

我尝试使用openNote(e)函数上获取数据,但我无法处理它。 e只是一个空对象。当我尝试e.key或e.date时,我得到了不确定。

1 个答案:

答案 0 :(得分:0)

我已用下面的这一行解决了这个问题。它是noteContainer文件。当我创建noteItems时,我将note.id作为参数来实现。并将其用作活动。

 noteList = props.noteList.map((note,i) =>(
        <NoteItem header={note.Header}
            explanation = {note.Explanation}
            date = {note.Date}
            key = {i}
            openNote = {() => props.openNote(note.id)}
            />