Как добавить больше компонентов динамически 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>
);
}
Поэтому каждый раз, когда вы нажимаете кнопку,
- _handleAddButton вызывать
- добавлены новые данные, обновите с помощью setState ()
- render () срабатывает.
- Больше
<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;