首页 > 解决方案 > React Native 动态创建的组件在第一次点击时不呈现

问题描述

我试图通过将列表项动态添加到数组中来创建一个列表,state然后使用map运算符对其进行迭代。但是,仅在第二次单击处理该setState方法的按钮后才会呈现新的列表项。有关解决此问题的任何指示?

...
constructor(props) {
    super(props);
    this.state = {
        requirements:[], // Placeholder array in state
        currentRequirement
    }
}
...

在我的render方法中,我有这个。

{
    this.state.requirements.map((el,i) => (
        <TouchableOpacity key={i}>
         <BulletItem text={el}/>
        </TouchableOpacity>
    ))
}
<FormInput 
    onChangeText={(value) => { 
        this.setState({ currentRequirement: value})}
    } 
    placeholder="Enter a new requirement"
/>

<Button 
    title="Add Requirement" 
    onPress={() => {
             this.onAddRequirementComponent()
    }}
/>

处理方法setState是这样的。

onAddRequirementComponent() {
    this.setState(previousState => ({
        requirements: [...previousState.requirements, this.state.currentRequirement],
        currentRequirement:''
    }))
}

更新:完整组件

import React, { Component } from 'react';
import { Text, View, StyleSheet, ScrollView, Picker, TouchableOpacity } from 'react-native';
import { BulletItem, TagCloud } from "../components/index";
import { Actions } from "react-native-router-flux";
import {
    Button,
    Header,
    FormInput,
    FormLabel,
} from 'react-native-elements';
export default class ListScreen extends Component {

    constructor(props) {
        super(props);
        this.state = {
            jobtype: '',
            level: '',
            requirements: [],
            benefits: [],
            currentRequirement: '',
            currentBenefit: ''
        }
    }
    render() {
        return (
            <View style={styles.container}>
                <Header
                    backgroundColor='#fff'
                    borderBottomWidth={0}
                    leftComponent={{ icon: 'corner-up-left', color: '#333', type: 'feather', onPress: () => { Actions.pop() } }}
                    centerComponent={{ text: 'Create New Job', fontFamily: 'VarelaRound-Regular', style: { color: '#333', fontSize: 18 } }}
                    rightComponent={{ icon: 'options', color: '#333', type: 'simple-line-icon' }} />
                <ScrollView>
                    <FormLabel>Job Title</FormLabel>
                    <FormInput placeholder="e.g. Full Stack Javascript Developer"/>
                    <FormLabel >REQUIREMENTS</FormLabel>
                    {
                        this.state.requirements.map((el, i) => (
                            <TouchableOpacity key={i}><BulletItem containerStyle={{ backgroundColor: '#EFF0F2', borderRadius: 4 }} style={{ backgroundColor: '#EFF0F2' }} text={el} /></TouchableOpacity>
                        ))
                    }
                                <FormInput 
                    onChangeText={(value) => { 
                        this.setState({ currentRequirement: value})}
                    } 
                    placeholder="Enter a new requirement"
                />

                <Button 
                    title="Add Requirement" 
                    onPress={() => {
                            this.onAddRequirementComponent()
                    }}
                />
                    <FormLabel style={{ fontFamily: 'VarelaRound-Regular', color: '#333' }} labelStyle={{ fontFamily: 'VarelaRound-Regular', color: '#333' }}>BENEFITS</FormLabel>
                    {
                        this.state.benefits.map((el, i) => (
                            <TouchableOpacity key={i}><BulletItem text={el} /></TouchableOpacity>
                        ))
                    }
                    <FormInput value={this.state.currentBenefit} onChangeText={(value) => { this.setState({ currentBenefit: value }) }} placeholder="3 years experience developing Javascript apps" />
                    <Button title="Add" onPress={() => { this.onAddBenefitComponent() }}/>
                    <Picker selectedValue={this.state.jobtype}
                        style={{ height: 50, width: '100%', backgroundColor: '#EFF0F2' }}
                        onValueChange={(itemValue, itemIndex) => this.setState({ jobtype: itemValue })}>
                        <Picker.Item label="Full Time" value="fulltime" />
                        <Picker.Item label="Part Time" value="parttime" />
                        <Picker.Item label="Contract" value="contract" />
                        <Picker.Item label="Remote" value="remote" />
                    </Picker>
                    <Picker selectedValue={this.state.level}
                        style={{ height: 50, width: '100%', backgroundColor: '#EFF0F2' }}
                        onValueChange={(itemValue, itemIndex) => this.setState({ level: itemValue })}>
                        <Picker.Item label="Junior" value="junior" />
                        <Picker.Item label="Mid-Level" value="mid" />
                        <Picker.Item label="Management" value="management" />
                        <Picker.Item label="Senior" value="senior" />
                    </Picker>
                </ScrollView>
            </View>
        );
    }

    onAddRequirementComponent() {
        if (this.state.currentRequirement)
            this.setState(previousState => ({
                requirements: [...previousState.requirements, this.state.currentRequirement],
                currentRequirement: ''
            }))
    }

    onAddBenefitComponent() {
        this.setState(previousState => ({
            benefits: [...previousState.benefits, this.state.currentBenefit],
            currentBenefit: ''
        }))

    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#fff',
    }
});

标签: javascriptreactjsreact-nativeecmascript-6

解决方案


这是核心逻辑部分,并且运行良好。我只使用了原生元素,比如TextInput. 我所做的唯一更改是通过添加@Tholle 的建议TextInput来完全控制.value={this.state.currentRequirement}previousState

class Test extends Component {
  state = {
    requirements: [],
    currentRequirement: ''
  }

  onAddRequirementComponent() {
    this.setState(previousState => ({
      requirements: [...previousState.requirements, previousState.currentRequirement],
      currentRequirement:''
    }))
  }

  render() {
    return(
      <View>
        <TextInput onChangeText={(value) => { 
          this.setState({ currentRequirement: value})}
        }
        value={this.state.currentRequirement}
        />

        { this.state.requirements.map((el,i) => (
            <Text key={i}>{el}</Text>
        ))}

        <Button 
          title="Add Requirement" 
          onPress={() => {
            this.onAddRequirementComponent()
          }}
        />
      </View>
    );
  }
}

推荐阅读