【问题标题】:React Native add multiple form onPress button and onchangeText issueReact Native 添加多个表单 onPress 按钮和 onchangeText 问题
【发布时间】:2019-08-07 07:35:11
【问题描述】:

我在 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


【问题讨论】:

  • 它在几分之一秒内显示什么值?
  • @V.Sambor 我输入的值
  • 在新输入中还是在之前创建的输入中?
  • @V.Sambor 最初没有表单,一旦我单击按钮,它将添加新表单,第一个表单正常工作,然后当我再次单击按钮添加第二个表单时,第二个表单有问题,但是当我添加第三种形式第二种形式工作正常,第三种形式给出问题等等
  • 您使用onChange而不是onChangeText的任何具体原因?

标签: javascript reactjs react-native


【解决方案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 的状态中创建另一个状态(如果之前未定义)变量,并与 indents 并排保持并保存调用它的 TextInput 的当前缩进的值。总而言之,它保存了最后键入的 TextInputs 缩进的缩进。

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

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

作为建议,请查看并获得对 JS 和 React 的 ES6 特性的更多见解。

如果您不知道自己的数据有多少级别,那么深度克隆可能会很棘手。 Lodash为此提供了非常有用的功能:https://lodash.com/docs/4.17.15#cloneDeep

您可以在 Exponack 上测试代码。如果您有任何不确定,请在 cmets 中告诉我。

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

【讨论】:

  • 嘿,代码运行良好,但你能在 react-native 中这样做吗goshakkk.name/array-form-inputs
  • 嗨,你能告诉我你在找哪个部分吗?这与您提供的链接几乎相同的逻辑。如果你的意思是具体的,请告诉我
  • 就像你写的有this.state = { formFields:[] };但我想要this.state = {name: "",shareholders: [{ name: "" }] }; 的代码
  • 如果您想删除一个字段,只需执行 formFields.filter((item, index) =&gt; index !== targetIndex) 就足够了。假设 targetIndex 是您要删除的内容
  • 我想要一个包含第一个键作为名称字符串的对象,第二个是 FormsFields,它是一个数组,其中包含具有键名的对象
猜你喜欢
  • 2020-05-30
  • 1970-01-01
  • 2022-08-22
  • 1970-01-01
  • 2019-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多