Reputation: 23407
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.
Upvotes: 4
Views: 9052
Reputation: 123
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;
Upvotes: 1
Reputation: 22797
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,
<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>
);
}
Upvotes: 16