首页 > 解决方案 > 用另一个组件的 props 打开一个组件

问题描述

我正在尝试制作一个简单的笔记应用程序。我在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 函数传递给大子组件。首先我将它传递给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>
    )
}

Open note 确实有效,我可以打开 newNote 组件。但我需要检索点击的 noteItem 信息。至少是键或订单号,以便我可以从具有 noteList 数组的状态中检索数据。

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

标签: javascriptreactjsreact-native

解决方案


我已经用下面的这行解决了这个问题。它是 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)}
            />

推荐阅读