First, I am from Web World(ReactJS), so not familier in React Native.
How to know which button was clicked?
Example:
const [titleOne, setTitleOne] = useState('A button 1');
const [titleTwo, setTitleTwo] = useState('A button 2');
const handlePress=(event)=>{
/*
if first button clicked,
I want to write: setTitleOne(Button 1 clicked);
if second button clicked,
I want to write: setTitleTwo(Button 2 clicked);
*/
}
<View>
<Button title={titleOne} onPress={handlePress} />
<Button title={titleTwo} onPress={handlePress} />
</View>
Thanks in advance.
const App = () => {
const [titleOne, setTitleOne] = useState('A button 1');
const [titleTwo, setTitleTwo] = useState('A button 2');
const handlePress = (event) => {
if (event == 1) {
setTitleOne("Button 1 clicked")
} else {
setTitleTwo("Button 2 clicked")
}
}
return (
<View>
<Button title={"titleOne"} onPress={() => handlePress(1)} />
<Button title={"titleTwo"} onPress={() => handlePress(2)} />
</View>
)
}
By passing an extra arg say name ...
const [titleOne, setTitleOne] = useState('A button 1');
const [titleTwo, setTitleTwo] = useState('A button 2');
const handlePress=(event, btnName)=>{
if(btnName === "one"){
setTitleOne("Button 1 clicked");
}
if(btnName === "two"){
setTitleTwo("Button 2 clicked");
}
}
<View>
<Button title={titleOne} onPress={(e)=>handlePress(e,"one")} />
<Button title={titleTwo} onPress={(e)=>handlePress(e,"two")} />
</View>
Related
so i want to load some data from my server using axios in React native. The data was retrieved successfully, but i don't know how to display it on the page. When i click button 'Load students' it does axios get method and after that calls method 'showStudents' but that method doesn't return anything. I really don't understand how rendering works in react native so i would appreciate any help and guidance. Also if there is easier way to do all of this, i'm open for suggestions.
export default function Students() {
const [s, setStudents] = useState('')
const getStudents = async () => {
try{
const {data: {students}} = await axios.get('http://192.168.1.2:3000/api/v1/students')
setStudents(students)
//console.log(students)
showStudents()
}
catch(error){
console.log(error)
}
}
const showStudents = () => {
return( <ScrollView>
{
s.map((student) => (
<ListItem key={student._id} bottomDivider>
<ListItem.Content>
<ListItem.Title>{student.firstName}</ListItem.Title>
<ListItem.Subtitle>{student.index}</ListItem.Subtitle>
</ListItem.Content>
</ListItem>
))
}
</ScrollView>)
}
return (
<View style={styles.container}>
<Button title='Load students' color='green' onPress={getStudents}/>
</View>
);
}
The function showStudents returns a JSX component, but not inside of the render function of the component Students.
You can just create a new JSX component and use conditional rendering in order to render it whenever the state s (I would call it students) is not undefined and has a length strictly greater than zero.
const [students, setStudents] = useState()
const getStudents = async () => {
try{
const {data: {students}} = await axios.get('http://192.168.1.2:3000/api/v1/students')
setStudents(students)
}
catch(error){
console.log(error)
}
}
return (
<View style={styles.container}>
<Button title='Load students' color='green' onPress={getStudents}/>
{
students && students.length > 0 ? <ScrollView>
{
students.map((student) => (
<ListItem key={student._id} bottomDivider>
<ListItem.Content>
<ListItem.Title>{student.firstName}</ListItem.Title>
<ListItem.Subtitle>{student.index}</ListItem.Subtitle>
</ListItem.Content>
</ListItem>
))
}
</ScrollView> : null
}
</View>
);
We could create a new component to make things more structured. Let us introduce StudentList.
export function StudentList({students}) {
return <ScrollView>
{
students.map((student) => (
<ListItem key={student._id} bottomDivider>
<ListItem.Content>
<ListItem.Title>{student.firstName}</ListItem.Title>
<ListItem.Subtitle>{student.index}</ListItem.Subtitle>
</ListItem.Content>
</ListItem>
))
}
</ScrollView>
}
Then, reuse this new component.
const [students, setStudents] = useState()
const getStudents = async () => {
try{
const {data: {students}} = await axios.get('http://192.168.1.2:3000/api/v1/students')
setStudents(students)
}
catch(error){
console.log(error)
}
}
return (
<View style={styles.container}>
<Button title='Load students' color='green' onPress={getStudents}/>
{
students && students.length > 0 ? <StudentList students={students} /> : null
}
</View>
);
i currently have a button on my posts page. I want to disable this button if the current user id is equal to the post user id.
I am using Formik to manage my state.
AppButton.js
function AppButton({ title, onPress}) {
return (
<TouchableOpacity style={[styles.button]} onPress={onPress}>
<Text style={styles.text}>{title}</Text>
</TouchableOpacity>
);
}
SubmitButton.js
import { useFormikContext } from "formik";
function SubmitButton({ title }) {
const { handleSubmit } = useFormikContext();
return <AppButton title={title} onPress={handleSubmit}/>;
}
Form.js
function MessageForm({ post,user }) {
return(
<SubmitButton title="Message"/>
PostScreen.js
function PostScreen({ route }) {
const post = route.params.post;
const { user } = useAuth();
clg(user.id) // this prints the id of the current user
clg(post.userId) / /this prints the userId of the post
return(
<Form post={post}/>
This might help
<SubmitButton title="Message" disabled={user.id === post.userId} />
function SubmitButton({ title, disabled }) {
const { handleSubmit } = useFormikContext();
return <AppButton title={title} onPress={handleSubmit} disabled={disabled}/>;
}
function AppButton({ title, onPress, disabled}) {
return (
<TouchableOpacity style={[styles.button]} onPress={onPress} disabled={disabled} >
<Text style={styles.text}>{title}</Text>
</TouchableOpacity>
);
}
I want to show at the beginning the reserve button and after the on press reserve is finished I need reserve button to hide and cancel button to appear and from then on vice versa. when one of the two buttons is visible the other disappear and vice versa.
my code:
const Unit = (props) => {
const [isReserveButtonVisible, setVisibilty] = React.useState(true);
const [isCancelButtonVisible, setVisibilty2] = React.useState(false);
return (
</View>
</Modal>
<Text>{props.title}</Text>
<Button
title="Click here to reserve"
visible={isReserveButtonVisible}
onPress={() => {
Alert.alert(
"Please be noted that the unit is reserved for the next hour only ",
".",
[
{
text: "Reserve",
onPress: () => {
setModal(true);
},
},
{ text: "Cancel" },
]
);
}}
/>
<Button
title="Click here to cancel"
visible={isCancelButtonVisible}
onPress={() => {
Alert.alert(
"Please be noted that now you are canceling your reservation",
".",
[
{
text: "Yes",
onPress: () => {
setSwitch(true);
},
},
{ text: "No" },
]
);
}}
/>
<Switch value={isSwitchEnabled} />
</View>
);
};
First, Button doesn't have visible props
Second, your code have some problem seems not clear with </View> and </Modal>
Third, you could use statement to control if you want to show in render like this:
import React, { useState } from "react";
...
export default function App() {
const [isReserveButtonVisible, setVisibilty] = useState(true);
const [isCancelButtonVisible, setVisibilty2] = useState(false);
return (
<>
{isReserveButtonVisible ? (
<Button
title="Click here to reserve"
visible={isReserveButtonVisible}
onPress={() => {
setVisibilty(false);
setVisibilty2(true);
}}
/>
) : null}
{isCancelButtonVisible ? (
<Button
title="Click here to cancel"
visible={isCancelButtonVisible}
onPress={() => {
setVisibilty(true);
setVisibilty2(false);
}}
/>
) : null}
</>
);
}
Take it a try :D
Code example build on sandbox
In the top on my app, I have 3 buttons: Load1, Load2, Add.
Load1 => Load data1 and display content
Load2 => Load data2 and display content
Add => Add data
3 Buttons:
class Comp1 extends Component {
...
renderMainPage() {
switch (this.state.selectedButton) {
case 'load1':
return <ListComp status="load1" />;
case 'closed':
return <ListComp status="load2" />;
case 'add':
return <AddComp status="add" />;
default:
break;
}
}
...
render() {
<View style={{ flex: 1 }}>
<Button onPress={() => this.setState({ selectedButton: 'load1' })} > <Text>Load1</Text>
</Button>
<Button onPress={() => this.setState({ selectedButton: 'load2' })} > <Text>Load2</Text>
</Button>
<Button onPress={() => this.setState({ selectedButton: 'add' })} > <Text>Add</Text>
</Button>
{this.renderMainPage()}
</View>
}
}
Buttons are working just fine and loading the correct content.
The ListComp:
componentDidMount() {
this.getData();
}
getData = async () => {
if (this.props.status === 'load1') {
await this.props.getLoad1();
} else if (this.props.status === 'load2') {
await this.props.getLoad2();
}
this.setState({
myData: this.props.data
});
};
Then the AddComp is just a form Component. It default loads with the "Load1" data. Then, I click on "Load2" it gets the load2 data. Then, I click on "Add" and click back on "Load1". It goes to this.props.getLoad1(), but did not update the "myData".
If I keep switching between "Load1" and "Load2", it work just fine.
I am new to react native
I am trying to make a search page, the search bar in the top while the result will show up below it. I want my search button to call getsearchlist, the state 'data' will be set, and my search list will be rerendered. How to do it? When i try my code, nothing happen, and soon will show up Network request failed and 'Possible unhandled promise rejection'
constructor(props) {
super(props);
this.state = {
data: '',
text: 'ducati'
};
this.getsearchlist = this.getsearchlist.bind(this);
}
async getsearchlist() {
//console.log(this.state.text);
let text = this.state.text;
let response = await fetch('https://www.blabla.com');
let responseXmlText = await response.text();
let newsitem = JSON.parse(responseXmlText);
let data = [];
for (var i = 0; i < newsitem.length; i++) {
var content = newsitem[i].content.rendered;
var title = newsitem[i].title.rendered;
var link = newsitem[i].link;
var re = /<img[^>]+src="?([^"\s]+)"?[^>]*\/>/g;
var results = re.exec(content);
var imgsrc = '';
if (results != null) {
imgsrc = results[1];
}
data.push({
title: title,
content: content,
img: imgsrc,
link: link
})
}
this.setState({
data: data
})
}
render() {
var datas = this.state.data;
return (
<Container>
<Header searchBar rounded>
<InputGroup>
<Icon name='ios-search' />
<Input placeholder='Search' onChangeText={(text) => this.setState({text})}
value={this.state.text}/>
<Icon name='ios-people' />
</InputGroup>
</Header>
<Content>
<Button onPress={this.getsearchlist}>
Search
</Button>
<List dataArray={datas}
renderRow={(data,sectionID, rowID) =>
<ListItem >
<Thumbnail square size={100} source={{uri: data.img}} />
<Text style={[ styles.titlestyle]}>{data.title}</Text>
</ListItem>
}>
</List>
</Content>
</Container>
);
Use something like this.
getSearchList = async () => {
.....
.....
}
And when you call it from the Button, call it just like you are calling it now.
<Button onPress={this.getSearchList} /> Search </Button>
Hope it helps :)
Now you can use the following syntax:
<Button onPress={async () => { ... your async code ... }} />Search</Button>