首页 > 解决方案 > 为什么在 React-Native 中绑定 Textarea 给我未定义?

问题描述

我目前正在开发一个梦想日记 React-Native 应用程序。我正在尝试将 Textarea 值双向绑定到父组件的状态。但是,我试图从子模态组件传递到父类的数据似乎并没有达到低谷。当我尝试提醒 event.target.value 发生变化时,我只会得到未定义。这可能是非常基本的事情,但我无法弄清楚我做错了什么。从 this.state.selectedDream 中选择值可以正常工作,否则在 dreamUpdateHandler 中。我只选择了我认为相关的代码部分,但如果需要,我可以发布更多。先感谢您。

这是父类。selectedDream 的状态为 null,因为我没有发布选择它的功能。

class Journal extends Component {

    state = {
        selectedDream: null,
    };

When the dream shown in modal is chosen it holds these values:


class NewDreamForm extends Component {

    state = {
        name: '',
        dreamsign: '',
        description: '',
    };

...

    dreamUpdateHandler = (event) => {
        this.setState({
            selectedDream: {
                id: this.state.selectedDream.id,
                name: this.state.selectedDream.name,
                dreamsign: this.state.selectedDream.dreamsign,
                // description: event.target.value,            
            },
        });

        alert(event.target.value);
    };

...


       <DreamModal
         selectedDream={this.state.selectedDream}
         updateDream={this.dreamUpdateHandler}
       /> 

这是无状态子模态组件中使用的Textarea。

    <Textarea
      rowSpan={20}
      value={props.selectedDream.description}
      onChange={props.updateDream}>
    </Textarea>

当我尝试在我的设备上键入时,警报只会给我“未定义”。关于问题原因的任何想法?

编辑:这里是要求的 newDreamForm 和 DreamModal :

import React, { Component } from 'react';
import { StyleSheet, View } from 'react-native';
import { Container, Header, Content, Form, Item, Input, Label, Button, Text, Textarea, Left, Body, Right, Title } from 'native-base';
import { Icon } from 'react-native-elements';
import { red } from 'ansi-colors';
import { SQLite } from 'expo';

const db = SQLite.openDatabase('dreams.db');

class NewDreamForm extends Component {

    state = {
        name: '',
        // date: this.createDate(),
        dreamsign: '',
        description: '',
    };

    nameChangedHandler = val => {
        this.setState({
          name: val,
        });
    };

    dreamsignChangedHandler = val => {
        this.setState({
          dreamsign: val,
        });
    };

    descriptionChangedHandler = val => {
        this.setState({
            description: val,
        });
    };

    // Myöhemmin myös tunnit ja minuutit
    createDate = () => {
        let dateCreator = new Date();
        let month = dateCreator.getMonth() + 1;
        let day = dateCreator.getDate();
        let year = dateCreator.getFullYear();

        let date = day + '.' + month + '.' + year;
        return date; 
    }

    createSqlTable = () => {
        db.transaction(tx => {
            let sql =
                'CREATE TABLE if not exists dream (' +
                'id integer PRIMARY KEY NOT NULL, ' +
                'name text NOT NULL, ' +
                // 'paiva date NOT NULL, ' +
                'dreamsign text NOT NULL, ' +
                'description text )';
            tx.executeSql(sql, null, this.DreamSubmitHandler, this.error);
        });
    }

    emptyForm = () => {
        this.setState({
          name: '',
          dreamsign: '',
          description: '',
        //   date: this.createDate(),
          description: '',
        });
      };

    DreamSubmitHandler = () => {

        db.transaction(tx => {
                let sql =
                'Insert INTO dream (name, dreamsign, description) VALUES (?, ?, ?)';

            tx.executeSql(
                sql,
                [
                    this.state.name,
                    this.state.dreamsign,
                    this.state.description
                ],
                this.success,
                this.error
            );
        })
    }

    // success = () => {
    //     alert('Dream saved!');
    // };

    error = () => {
        alert("There was an error")
    };

  render() {
    return (

        <Container style={styles.container}>
            <Content>
                <Form>
                    <Item floatingLabel>
                        <Label>Name the dream:</Label>
                        <Input
                            value={this.state.name}
                            onChangeText={this.nameChangedHandler}
                        />
                    </Item>
                    <Item floatingLabel>
                        <Label>Dreamsign:
                        </Label>
                        <Input
                            onChangeText={this.dreamsignChangedHandler}
                            value={this.state.dreamsign}/>
                    </Item>

                    <Textarea
                        style={styles.textarea}
                        rowSpan={20}
                        bordered placeholder="Describe your dream here"
                        onChangeText={this.descriptionChangedHandler}
                        value={this.state.description} />

                    <Button
                        style={styles.button}
                        onPress={this.createSqlTable}
                        // onPress={this.emptyForm}
                        >
                        <Text>Submit</Text>
                    </Button>

                </Form>
            </Content>

        </Container>
    );
  }
}

const styles = StyleSheet.create({
    container: {

    },

    button: {
        margin: 10,
    },

    textarea: {
        marginTop: 20,
        margin: 10,
    }
});

export default NewDreamForm;

模态在这里:

import React from 'react';
import { Modal, View, Text, Button, StyleSheet, TouchableWithoutFeedback, TextInput } from 'react-native';
import { Constants } from 'expo';
import { Container, Header, Content, Form, Item, Input, Label, Textarea, } from 'native-base';

const dreamModal = props => {
  let modalContent = null;

  if (props.selectedDream) {

    // let descValue = props.selectedDream.description;

    modalContent = (
      <View style={styles.container}>

        <Text style={styles.nameStyle}>
          Title: {props.selectedDream.name}
        </Text>

        <Text style={styles.nameStyle}>
          Dream sign: {props.selectedDream.dreamsign}
        </Text>

        <Text style={styles.nameStyle}>
          date: Under Construction
        </Text>

        <Text style={styles.nameStyle}>
          Description:
        </Text>

        <TextInput
          multiline={true}
          numberOfLines={10}
          editable={true}
          style={styles.descriptionStyle}
          value={props.selectedDream.description}
          onChangeText={props.updateDream}>
        </TextInput>

        <Button
            title="Close"
            onPress={props.closeModal}/>
        <Button
            title="Remove"
            onPress={() => this.props.removeDream(props.selectedDream.id)}>
        </Button>

    </View>
    );
  }

  return (
    <Modal visible={props.selectedDream !== null} animationType="fade">
      <View>
        {modalContent}
      </View>
    </Modal>
  );
};

const styles = StyleSheet.create({
  container: {
    paddingTop: Constants.statusBarHeight,
  },
  nameStyle: {
    margin: 20,
  },
  descriptionStyle: {
    margin: 10,
  },
});

export default dreamModal;

和日记还:

import React, { Component } from 'react';
import { StyleSheet, View, } from 'react-native';
import DreamList from './components/DreamList/DreamList';
import { Header, Left, Right, Body, Title, Text, List, ListItem, Container, Content, Button } from 'native-base';

import DreamModal from './components/DreamList/DreamModal/DreamModal';

import { SQLite } from 'expo';

const db = SQLite.openDatabase('dreams.db');

class Journal extends Component {

    state = {
        dreams: [],
        selectedDream: null,
    };

    componentDidMount =  () => {
        db.transaction(tx => {
            let sql =
                'CREATE TABLE if not exists dream (' +
                'id integer PRIMARY KEY NOT NULL, ' +
                'name text NOT NULL, ' +
                // 'paiva date NOT NULL, ' +
                'dreamsign text NOT NULL, ' +
                'description text )';
            tx.executeSql(sql);
        });
    };

    listDreams = () => {
        db.transaction(tx => {
            tx.executeSql('select * from dream', null, this.success, this.error);
        });
    };

    success = (tx, results) => {
        this.setState({ dreams : results.rows._array });
    };

    error = (tx, error) => {
        alert('Could not list your dreams' + error);
    };


    dreamSelectedHandler = key => {
        this.setState(prevState => {
          return {
            selectedDream: prevState.dreams.find(dream => {
              return dream.id === key;
            }),
          };
        });
    };

    removeError = () => {
        alert('Sorry! Could not remove this dream');
    };

    closeModalHandler = () => {
        this.setState({
            selectedDream: null,
        });
    };

    deleteAllHandler = () => {
        db.transaction(tx => {
            let sql =
            'DELETE FROM dream';
            tx.executeSql(sql);      
        });   
    }

    removeDreamHandler = (id) => {
        db.transaction(tx => {
            let sql =
            'DELETE FROM dream WHERE id = ?';
            tx.executeSql( sql, [id] );
        });

        this.setState({
            selectedDream: null,
        });
    };


    dreamUpdateHandler = (event) => {
        this.setState({
            selectedDream: {
                id: this.state.selectedDream.id,
                name: this.state.selectedDream.name,
                dreamsign: this.state.selectedDream.dreamsign,
                description: event.target.value,            
            },
        });

        alert(event.target.value);

        // db.transaction(tx => {
        //     let sql =
        //     'UPDATE dream SET id = ?, name = ?, dreamsign = ?, description = ?'
        //     // 'DELETE FROM dream WHERE id = ?';
        //     tx.executeSql( sql,
        //         [
        //             this.state.selectedDream.id,
        //             this.state.selectedDream.name,
        //             this.state.selectedDream.dreamsign,
        //             this.state.selectedDream.description,
        //         ]);
        // });

        // this.setState({
        //     selectedDream: null,
        // });

    };

    render() {

        this.listDreams();
        if (this.state.dreams.length === 0) {
          return (
            <Container style={styles.dreamList}>
                <Content>
                    <Text>You have not written down any dreams.</Text>
                </Content>
            </Container>
          )
        }

        return (
            <View style={styles.container}>

                <Header>
                    <Left/>
                    <Body>
                        <Title>Journal</Title>
                    </Body>
                    <Right />
                </Header>

                <DreamModal
                    selectedDream={this.state.selectedDream}
                    closeModal={this.closeModalHandler}
                    removeDream={this.removeDreamHandler}
                    updateDream={this.dreamUpdateHandler}
                /> 

                <DreamList
                    dreams={this.state.dreams}
                    style={styles.dreamList}
                    onDreamSelected={this.dreamSelectedHandler}/>

                <Button
                    onPress={this.deleteAllHandler}>
                    <Text>Delete</Text>
                </Button>
            </View>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
    },
    dreamList: {
        padding: 25,
    },
});

export default Journal;

Edit2:在帖子中添加了 newDreamForm、DreamModal 和 Journal。我还将模态中的onChange更改为onChangeText。但是将 Textarea 更改为 TextInput 并不能解决问题。当我尝试输入 TextInput 时出现错误:“未定义不是对象(正在评估 'event.target.value')

标签: javascriptreactjsreact-native

解决方案


推荐阅读