Как добавить больше компонентов динамически React Native

Я хочу добавить больше компонентов после нажатия на кнопку. Можете ли вы поделиться кодом или идеей, чтобы я мог реализовать? Как показано на рисунке, каждый раз, когда пользователь нажимает кнопку добавления, добавляется одна строка / компонент.

1 ответ

Решение

Это где state сияние,

например:

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>
    );
}

Поэтому каждый раз, когда вы нажимаете кнопку,

  1. _handleAddButton вызывать
  2. добавлены новые данные, обновите с помощью setState ()
  3. render () срабатывает.
  4. Больше <MyComponent> добавлен в просмотр и показ

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

2017/8/3 отредактировано:

если вы хотите удалить дальше <MyComponent> опора key следует позаботиться о. key действовать как детектор изменений для реагирующей структуры, ключ автоинкремента подойдет для вашего случая. пример:

_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>
    );
}

Я думаю, вы можете спросить, например, добавить задачу в приложение todo. Мой ответ таков. В начале есть массив данных с тремя элементами, которые я сохранил в состоянии компонента, и эти 3 элемента отображаются на экране. Затем я использую модальное окно, чтобы принять ввод от пользователя и сохранить его как newInput в состоянии компонента. Затем я использовал кнопку, чтобы добавить этот newInput к данным в функции handleModalClick. Затем в массив данных добавляется значение newInput. Все элементы в массиве данных отображаются на экране.

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;

Другие вопросы по тегам