React Native动态创建的组件在第一次单击时不会呈现

时间:2018-08-10 12:49:45

标签: javascript reactjs react-native ecmascript-6

我试图通过将列表项动态添加到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',
    }
});

1 个答案:

答案 0 :(得分:0)

这是核心逻辑部分,可以正常运行。我只使用了TextInput之类的本机元素。我添加TextInput并加上@Tholle建议使用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>
    );
  }
}