简体   繁体   中英

How To Add More component dynamically React Native

I want to add more components after clicking on the button. Can you share code or an idea so that I can implement? As the image shows, every time when user click on the add button, one row / component will be added.

It's where state shining of,

for example:

constructor(props) {
   super(props);

   this._handleAddButton = this._handleAddButton.bind(this);

   this.state = {    /* initial your state. without any added component */
      data: []
   }
}

_handleAddButton() {
    let newly_added_data = { title: 'new title', content: 'new content goes here' };

    this.setState({
        data: [...this.state.data, newly_added_data]
    });
}

render() {
    let added_buttons_goes_here = this.state.data.map( (data, index) => {
        return (
            <MyComponent key={index} pass_in_data={data} />
        )
    });

    return (
        <View>
            <Button title="Add more" onPress={this._handleAddButton} />
            {added_buttons_goes_here}
        </View>
    );
}

So every time you click the button,

  1. _handleAddButton get called
  2. a new data is added, update with setState()
  3. render() get triggered.
  4. more <MyComponent> added into View and show

================

2017/8/3 edited:

if you want to further delete <MyComponent> , the prop key should be taken care of. The key act as change detector for react framework, an auto-increment key would suit your case. example:

_handleAddButton() {
    let newly_added_data = {
        /* psedo code to simulate key auto increment */
        key: this.state.data[this.state.data.length-1].key+1,
        title: 'new title',
        content: 'new content goes here'
    };

    this.setState({
        data: [...this.state.data, newly_added_data]
    });
}

_handleRemoveButton(key) {
    let result = this.state.data.filter( (data) => data.key !== key );

    this.setState({
        data: result,
    });
}

render() {
    let added_buttons_goes_here = this.state.data.map( (data, index) => {
        return (
            <MyComponent key={data.key} pass_in_data={data}>
                /// psedo code of pass-in remove button as a children
                <Button title="Remove" onPress={ () => this._handleRemoveButton(data.key) } />
            </MyComponent>
        )
    });

    return (
        <View>
            <Button title="Add more" onPress={this._handleAddButton} />
            {added_buttons_goes_here}
        </View>
    );
}

I think you may be asking like adding task in todo app. My answer is as follows. In the beginning, there is an array as data with three items as I stored in the state of the component and those 3 items are displaying in the screen. Then I use a modal to take the input from the user and store that input as newInput in the state of the component. Then I used a button to add that newInput to the data in handleModalClick function. Then the newInput value is added to the data array. The all the elements in the data array are displaying on the screen.

 import React, { Component } from "react"; import { SafeAreaView, View, FlatList, StyleSheet, Text, TextInput, Button, Modal, TouchableHighlight, Alert, TouchableOpacity } from "react-native"; import Constants from "expo-constants"; import uuid from "uuid/v1"; import { Ionicons } from "@expo/vector-icons"; export class Test extends Component { constructor(props) { super(props); this.state = { data: [ { id: 1, title: "First Item" }, { id: 2, title: "Second Item" }, { id: 3, title: "Third Item" } ], modalVisible: false, newInput: "" }; } setModalVisible(visible) { this.setState({ modalVisible: visible }); } handleModalClick = () => { this.setState( { data: [...this.state.data, { id: uuid(), title: this.state.newInput }] }, this.setState({ newInput: "" }) ); }; render() { return ( <SafeAreaView style={styles.container}> <FlatList data={this.state.data} renderItem={({ item }) => ( <View style={styles.item}> <Text style={styles.title}>{item.title}</Text> </View> )} keyExtractor={item => item.id} /> <View style={{ marginTop: 22 }}> <Modal animationType="slide" transparent={false} visible={this.state.modalVisible} onRequestClose={() => { Alert.alert("Modal has been closed."); }} > <View style={{ marginTop: 22 }}> <View> <TextInput placeholder="ENTER" onChangeText={text => { this.setState({ newInput: text }); }} value={this.state.newInput} /> <Button title="click" onPress={this.handleModalClick} /> <TouchableHighlight onPress={() => { this.setModalVisible(!this.state.modalVisible); }} > <Ionicons name="md-close-circle" size={50} color="red" /> </TouchableHighlight> </View> </View> </Modal> <TouchableOpacity onPress={() => { this.setModalVisible(true); }} > <Ionicons name="md-add-circle" size={100} color="violet" /> </TouchableOpacity> </View> </SafeAreaView> ); } } const styles = StyleSheet.create({ container: { flex: 1, marginTop: Constants.statusBarHeight }, item: { backgroundColor: "#f9c2ff", padding: 10, marginVertical: 8, marginHorizontal: 16 }, title: { fontSize: 18 }, input: { borderWidth: 2 } }); export default Test;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM