React Native添加多种形式的onPress按钮和onchangeText问题

时间:2019-08-07 07:35:11

标签: javascript reactjs react-native

我已经在 React native 中创建了动态表单,如果用户单击该按钮,则会显示一个按钮,它将在该按钮上方添加新表单。用户单击按钮的次数将添加该表格。我已经做到了,但是在文本更改期间遇到了问题。

问题是,当我开始输入表格时,它首先显示秒的值,然后变为空

下面是我的代码 我尝试过


import React, { PureComponent } from 'react'
import { 
    Text, 
    View,
    TextInput
 } from 'react-native'
import { TouchableOpacity } from 'react-native-gesture-handler';

export class IndentForm extends PureComponent {

    constructor(props) {
        super(props);
        this.state = {
         indents:[]
        };
      }

      addInput(){
          this.setState({ indents:[...this.state.indents, ""]})
      }

      onTextChange = (event, index) => {
        const { indent } = event.nativeEvent;
          this.state.indents[index] = indent

        this.setState({indent})
      }

    render() {
        return (
            <View style={{flex:1}}>
                {
                    this.state.indents.map((indent,index) => {
                        return(
                            <View key={index}>

                            <TextInput  
                                name="indent"
                                style={{height: 40,backgroundColor: 'azure', fontSize: 20}}  
                                placeholder="Type here to translate!"  
                                value={indent}   
                                onChange={(event)=> this.onTextChange(event,index)} 
                             />  
                        </View>
                        )

                    })
                }
                <TouchableOpacity 
                    style={{ height:30, width:70, backgroundColor:'blue'}}
                    onPress={this.addInput.bind(this)}>
                    <Text>Add Form</Text>
                </TouchableOpacity>
            </View>
        )
    }
}

export default IndentForm


1 个答案:

答案 0 :(得分:1)

我已经检查了您的snack,并进行了一些更改。这是最终的工作版本:

import React, { PureComponent } from 'react'
import { 
    Text, 
    View,
    TextInput
 } from 'react-native'
import { TouchableOpacity } from 'react-native-gesture-handler';

export class App extends PureComponent {

    constructor(props) {
        super(props);
        this.state = {
         formFields:[{value: ''}]
        };
      }

      addInput = () => {
        const existingFormFields = this.state.formFields.map(fields => ({...fields}))
        const allFormFieldsAfterAddingNew = [...existingFormFields, {value: ''}]

        this.setState({formFields: allFormFieldsAfterAddingNew})
      }

      onTextChange = (text, index) => {
        const existingFormFields = this.state.formFields.map(fields => ({...fields}))
        let targetField = {...existingFormFields[index]}
        targetField.value = text
        existingFormFields[index] = targetField

        this.setState({formFields: existingFormFields})
      }

    render() {
        return (
            <View style={{flex:1, marginTop:30}}>
                {
                    this.state.formFields.map((field, index) => {
                        return(
                            <View key={index}>

                            <TextInput  
                                name="indent"
                                style={{height: 40,backgroundColor: 'azure', fontSize: 20}}  
                                placeholder="Type here to translate!"  
                                value={field.value}   
                                onChangeText={(text)=> this.onTextChange(text, index)} 
                             />  
                        </View>
                        )

                    })
                }
                <TouchableOpacity 
                    style={{ height:30, width:70, backgroundColor:'blue'}}
                    onPress={this.addInput}>
                    <Text>Add Form</Text>
                </TouchableOpacity>
            </View>
        )
    }
}

export default App

我试图尽可能多地使用一些有用的/上下文相关的名称,以使您了解正在发生的事情。但是,让我们在这里介绍一下核心概念:

  1. 使addInput功能为箭头功能,因为它位于类组件中,所以箭头功能会自动绑定,绑定可能会造成混淆。

  2. 您在小吃中this.setState({indent})做过this.setState({indent: indent})。请了解,这会在名为indent的状态下创建另一个state(如果之前未定义)变量,并且与indents并排保持着从中调用的TextInput的当前缩进值。总之,它保留了最后键入的TextInputs的缩进量。

  3. addInput基本上是将对象推入状态中的表单字段列表。在创建状态对象之前,我们正在创建一个复制/深克隆状态对象。不建议您使用之前的声明this.state.indents[index] = indent切勿在没有setState的情况下改变状态。通过this.state.formFields.map(fields => ({...fields})),我们首先创建了formFields数组的副本/克隆,然后返回我们所做的{...fields}的每个项目,现在我们正在上下文中创建对象的副本/克隆并返回它。这样,我们确保在处理数据时状态不会意外更改。最后,我们只添加一个带有空白value的新条目,并使用setState更新状态,然后看到一个新的字段!

  4. 对于更新每个数据,我们所做的与您最初在snack中所做的相同。查找索引并更新值。请注意,数据流与上一点相似。我们使用formFields的deepClone,从克隆中获取目标,更新目标,然后在获取的克隆中替换新值对象并将其设置为新状态。与第3点非常相似。

作为建议,请先结帐并获得有关JS和React的ES6功能的更多见解。

如果您不知道数据中有多少级,则深克隆可能会很棘手。 Lodash为此具有非常有用的功能:https://lodash.com/docs/4.17.15#cloneDeep

您可以在博览会小吃上测试代码。如果您不确定什么,请在评论中让我知道。

希望它对您有所帮助。干杯!