I'am having trouble with modal because I have some in a "Datails screen" with Flatlist and it is working fine, actually. But the thing is, before navigating to my "Datails screen" the user will first see the "Category screen", and here is where the problem. Because I didn't type any modal at my "Category screen", but whenever I click on any button in there a modal is showing, it looks very tricky for me.
Here is my code
Details.js (this is the only screen where I want to display my modal)
import React, {Component} from 'react';
import {Text, TouchableHighlight, View,
StyleSheet, Platform, FlatList, AppRegistry,
TouchableOpacity, RefreshControl, Dimensions, Modal
} from 'react-native';
export default class Details extends Component {
static navigationOptions = {
title: ''
};
constructor()
{
super ()
this.state = {
showModal: true
}
}
state = {
data: [],
refreshing: false
};
fetchData = async() => {
const { params } = this.props.navigation.state;
const response_Cat = await fetch('http://192.168.254.100:3307/categories/' + params.id);
const category_Cat = await response_Cat.json();
this.setState({data: category_Cat});
};
componentDidMount() {
this.fetchData();
};
_onRefresh() {
this.setState({ refreshing: true });
this.fetchData().then(() => {
this.setState({ refreshing: false })
});
};
render() {
const { params } = this.props.navigation.state;
return (
<View style = { styles.container }>
<FlatList
data = { this.state.data }
renderItem = {({ item }) =>
<TouchableOpacity style = { styles.buttonContainer }>
<Text style = { styles.buttonText }
onPress = { () => { this.setState({showModal:true}) } }>{ item.menu_desc } { item.menu_price }</Text>
</TouchableOpacity>
}
keyExtractor={(item, index) => index.toString()}
/*refreshControl = {
<RefreshControl
refreshing = { this.state.refreshing }
onRefresh = { this._onRefresh.bind(this) }
/>
}*/
/>
<View>
<Modal
onRequestClose={() => console.warn('no warning')}
visible={this.state.showModal}
>
<TouchableOpacity style = { styles.buttonContainer }>
<Text style = { styles.buttonText }
onPress = { () => { this.setState({ showModal:false }) } }>Hello</Text>
</TouchableOpacity>
</Modal>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
container:{
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
},
pageName:{
margin:10,fontWeight:'bold',
color:'#000', textAlign:'center'
},
productBox:{
padding:5,margin:10,borderColor:'orange',borderBottomWidth:1
},
price:{
padding:5, color:'orange',fontWeight:'bold',textAlign:'center'
},
proName:{
padding:5,color:'blue',textAlign:'center'
},
buttonContainer: {
backgroundColor: '#f7c744',
paddingVertical: 10,
borderRadius: 30,
marginBottom: 10,
},
buttonText: {
textAlign: "center",
color: 'rgb(32, 53, 70)',
fontWeight: 'bold',
fontSize: 18
},
modalView: {
backgroundColor: "#aaa",
height: 150,
justifyContent: 'center',
alignItems: 'center'
},
closeText: {
backgroundColor: '#333',
color: '#bbb',
padding: 5,
margin: 20
}
})
//AppRegistry.registerComponent('Details', () => Details);
categories.js (this is the page where I don't type any modal code, I guess)
import React, {Component} from 'react';
import {Text, TouchableHighlight, View,
StyleSheet, Platform, FlatList, AppRegistry,
TouchableOpacity, RefreshControl
} from 'react-native';
export default class Categories extends Component {
state = {
data: [],
refreshing: false
};
fetchData = async() => {
const { params } = this.props.navigation.state;
const response_Cat = await fetch('http://192.168.254.100:3307/categories/');
const category_Cat = await response_Cat.json();
this.setState({data: category_Cat});
};
componentDidMount() {
this.fetchData();
};
_onRefresh() {
this.setState({ refreshing: true });
this.fetchData().then(() => {
this.setState({ refreshing: false })
});
}
render() {
const { params } = this.props.navigation.state;
return (
<View style = { styles.container }>
<FlatList
data = { this.state.data }
renderItem = {({ item }) =>
<TouchableOpacity style = {styles.buttonContainer}>
<Text style = {styles.buttonText}
onPress = { () => this.props.navigation.navigate('Details', { id: item.cat_id }) }>{ item.cat_name }</Text>
</TouchableOpacity>
}
keyExtractor={(item, index) => index.toString()}
refreshControl = {
<RefreshControl
refreshing = { this.state.refreshing }
onRefresh = { this._onRefresh.bind(this) }
/>
}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container:{
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
},
pageName:{
margin:10,fontWeight:'bold',
color:'#000', textAlign:'center'
},
productBox:{
padding:5,margin:10,borderColor:'orange',borderBottomWidth:1
},
price:{
padding:5, color:'orange',fontWeight:'bold',textAlign:'center'
},
proName:{
padding:5,color:'blue',textAlign:'center'
},
buttonContainer: {
backgroundColor: '#f7c744',
paddingVertical: 10,
borderRadius: 30,
marginBottom: 10,
},
buttonText: {
textAlign: "center",
color: 'rgb(32, 53, 70)',
fontWeight: 'bold',
fontSize: 18
},
})
AppRegistry.registerComponent('Categories', () => Categories);
In your details.js you kept showModal: true in constructor itself.
Change it to false, and make it true whenever you want to show a modal.
I guess you should make it true after you have successfully fetched data. i.e keep it in fetchData()
this.setState({data: category_Cat, showModal:true});
Related
We are currently developing based on React Native.
And I received data by GET request through API document,
and I created scroll view through MAP method.
So now I'm trying to make it possible to choose,
but if I choose one, it's all chosen.
How can I make you choose one by one if I choose one from my code?
import React, { useEffect, useState } from "react";
import { SvgCssUri } from "react-native-svg";
import { DeviceEventEmitter } from "react-native";
import {
View,
StyleSheet,
TouchableHighlight,
Text,
ScrollView,
Image,
} from "react-native";
import {
widthPercentageToDP as wp,
heightPercentageToDP as hp,
} from "react-native-responsive-screen";
import axios from "axios";
import BouncyCheckbox from "react-native-bouncy-checkbox";
const Select = ({ navigation }) => {
let bouncyCheckboxRef = null;
const [bodyType, setBodyType] = useState([]);
const [standardSelected, setStandardSelected] = useState(false);
const [isSelected, setSelected] = useState(false);
const bodyGetData = async () => {
let body = [];
try {
let config = {
method: "get",
url:
"http://everyweardev-env.eba-azpdvh2m.ap-northeast-2.elasticbeanstalk.com/api/v1/user/bodyType/male",
headers: {},
};
axios(config).then(function (response) {
response.data.data.map((u) => {
switch (u.bodyType) {
case "standard":
body.push({ bodyType: "스탠다드", imgUrl: u.imgUrl, key: 1 });
break;
case "reverseTriangle":
body.push({ bodyType: "역삼각형", imgUrl: u.imgUrl, key: 2 });
break;
case "triangle":
body.push({ bodyType: "삼각형", imgUrl: u.imgUrl, key: 3 });
break;
case "circle":
body.push({ bodyType: "원형", imgUrl: u.imgUrl, key: 4 });
break;
case "hourglass":
body.push({ bodyType: "직사각형", imgUrl: u.imgUrl, key: 5 });
break;
}
});
return setBodyType(body);
});
} catch (err) {
console.log(err);
}
};
useEffect(() => {
const unsubscribe = navigation.addListener("focus", () => {
bodyGetData();
});
return unsubscribe;
}, [navigation]);
const onClick = (e) => {
console.log(e);
bodyType.map((u) => {
switch (u.bodyType) {
case u.bodyType === "스탠다드":
setSelected(!isSelected);
console.log(isSelected);
break;
case "역삼각형":
setSelected(!isSelected);
break;
}
});
};
return (
<View style={styles.container}>
<Text
style={{ fontSize: wp("5.5%"), fontWeight: "bold", marginBottom: 21 }}
>
자신의 체형을 선택해 주세요
</Text>
<View style={{ flexDirection: "row", marginBottom: hp("10%") }}>
<Text style={{ fontSize: wp("4.5%"), marginRight: wp("1%") }}>
더 정확한 평가를 받으실 수 있습니다
</Text>
<Image
source={require("../../images/smile.png")}
style={{ marginTop: hp("0.5%") }}
/>
</View>
<ScrollView horizontal={true} showsHorizontalScrollIndicator={true}>
{bodyType.map((data) => (
<>
<TouchableHighlight
style={styles.bodySelect}
value={data.bodyType}
onPress={onClick}
// onPress={() => bouncyCheckboxRef?.onPress()}
>
<>
<BouncyCheckbox
isChecked={!isSelected}
ref={(ref) => (bouncyCheckboxRef = ref)}
size={25}
fillColor="black"
unfillColor="#FFFFFF"
iconStyle={{ borderColor: "white" }}
textStyle={{ fontFamily: "JosefinSans-Regular" }}
disableBuiltInState
onPress={onClick}
style={{
alignSelf: "flex-start",
marginLeft: wp("3%"),
marginTop: hp("2%"),
}}
/>
<SvgCssUri
uri={data.imgUrl}
width="90%"
height="60%"
marginTop="-5%"
key={data.key}
/>
<Text style={styles.bodytype}>{data.bodyType}</Text>
</>
</TouchableHighlight>
</>
))}
</ScrollView>
<TouchableHighlight
style={styles.button}
onPress={() => {
navigation.navigate("얼굴형 정보 입력");
}}
underlayColor="gray"
>
<>
<Text style={styles.text}>선택 완료</Text>
</>
</TouchableHighlight>
</View>
);
};
const styles = StyleSheet.create({
container: {
justifyContent: "center",
alignItems: "center",
marginTop: hp("5%"),
},
button: {
justifyContent: "center",
alignItems: "center",
width: wp("70%"),
height: hp("7%"),
color: "white",
backgroundColor: "black",
borderRadius: 10,
marginTop: hp("17%"),
},
text: {
color: "white",
fontSize: wp("5.2%"),
fontWeight: "bold",
},
bodySelect: {
marginLeft: 16,
marginRight: 16,
width: wp("70%"),
height: hp("35%"),
alignItems: "center",
borderRadius: 30,
backgroundColor: "#ffffff",
shadowColor: "#000",
shadowOffset: {
width: 0,
height: 3,
},
shadowOpacity: 0.25,
shadowRadius: 3.84,
elevation: 5,
},
bodytype: {
marginTop: hp("3%"),
fontWeight: "bold",
fontSize: wp("8%"),
},
});
export default Select;
this example explain how to select individual choice.
do these steps :
//define state to save selected value inside it
const [selected, setSelected] = React.useState();
//handle item onPress
const onPress = (item) => {
setSelected(item);
}
//check if item selected
const isSelected = (item) => {
return selected?.unique_id === item.unique_id;
}
//and in render function
<ScrollView>
{
data.map((item, index) => {
return(
<ItemComponent
onPress={() => setSelected(item)}
style={isSelected(item) ? selectedStyle : defaultStyle}>
</ItemComponent>
)
})
}
</ScrollView>
full code try snack here
import * as React from 'react';
import { Text, View, StyleSheet, ScrollView, TouchableOpacity} from 'react-native';
export default function App() {
const [selected, setSelected] = React.useState();
const data = [
{
unique_id : 1,
text : "item one"
},
{
unique_id : 2,
text : "item two"
},
{
unique_id : 3,
text : "item three"
},
{
unique_id : 4,
text : "item four"
}
];
const onPress = (item) => {
setSelected(item);
}
const isSelected = (item) => {
return selected?.unique_id === item.unique_id;
}
return (
<ScrollView>
{
data.map((item, index) => {
return(
<TouchableOpacity
key={item.unique_id}
onPress={() => {
setSelected(item);
}}
style={{
padding : 25,
margin : 10,
backgroundColor : isSelected(item) ? "red" : "#eee"
}}
>
<Text>{item.text}</Text>
</TouchableOpacity>
)
})
}
</ScrollView>
);
}
I've implemented an app based on react native. This app shows me a list via swipelistview. But I have a Problem. when list add new items after scroll down, swipelistview won't work properly. In fact it works by Accident. I don't know where i've made mistake.
this is my code:
import React , {Component} from 'react';
import { StyleSheet, Text, View, FlatList ,ActivityIndicator,Animated , TouchableOpacity, Alert } from 'react-native';
import { SwipeListView } from 'react-native-swipe-list-view';
import { Container, Header, Content, Accordion ,Icon ,Item, Input , Button ,ActionSheet , Card, CardItem, Body} from "native-base";
var DESTRUCTIVE_INDEX = 3;
var CANCEL_INDEX = 4;
class App extends Component {
constructor(props) {
super(props);
this.actionSheet = null;
}
state = {
data: [],
filteredData: [],
page: 1,
loading: false,
error: null,
spinner: false,
searchText:'',
lety:false,
refreshing: false
};
componentDidMount() {
console.disableYellowBox = true;
this.fetchData();
}
handleLoadMore = () => {
this.setState(
{
page: this.state.page + 1
},
() => {
this.fetchData();
}
);
};
fetchData = () => {
const page = this.state.page;
this.setState({ loading: true });
let response = fetch(
'http://webgispro.ir/home/GetWords/' + page ,
{
method: "POST"
}
).then((response) => response.json())
.then((responseJson) => {
this.setState(
{
data : page === 1 ? Array.from(responseJson): [...this.state.data, ...responseJson] ,
loading: false,
refreshing: false
})
})
.catch((error) => {
this.setState({ error, loading: false });
});
};
searchData = (searchText) => {
this.setState({searchText: searchText.toLowerCase()});
if (searchText =='') {
this.setState({filteredData: []});
this.setState({lety:false})
return false;
}
let filteredData = this.state.data.filter(function (item) {
return item.Word.toLowerCase().includes(searchText.toLowerCase());
});
this.setState({lety : filteredData.length == 0 ? true : false})
this.setState({filteredData: filteredData});
};
renderHeader = () => {
return <Searchbar
style={{ width:'100%' }}
inputStyle={{borderWidth: 0}}
round={false}
lightTheme={true}
placeholder="Search..."
autoCapitalize='none'
autoCorrect={false}
onChangeText={this.searchData}
value={this.state.searchText}
/>
};
renderFooter = () => {
if (!this.state.loading) return null;
return (
<View
style={{
paddingVertical: 20,
borderTopWidth: 1,
borderColor: "#CED0CE"
}}
>
<ActivityIndicator animating ={true} color="blue" style={{height: 80, marginTop: 10, opacity: 1 }} size="large" />
</View>
);
};
renderSeparator = () => {
return (
<View
style={{
height: 1,
width: "100%",
backgroundColor: "#CED0CE",
//marginLeft: "14%"
}}
/>
);
};
handleRefresh = () => {
this.rowHeightAnimatedValues = {};
this.setState(
{
page: 1,
refreshing: true
},
() => {
this.fetchData();
}
);
};
editItem = key => () => {
var example = this.state.data.find(o=>o.Id == key).Example
if ( this.actionSheet !== null ) {
const title = <Text style={{ color: 'black', fontSize: 23 }}>{example}</Text>
this.actionSheet._root.showActionSheet(
{
options: [] ,
cancelButtonIndex: CANCEL_INDEX,
destructiveButtonIndex: DESTRUCTIVE_INDEX,
title:title
}, (i) => console.log(i));
}
}
deleteItem = key => () => {
Alert.alert(
"???",
"??? ???? ??? ????? ????? ??",
[
{
text: "???",
onPress: () => console.log("Cancel Pressed"),
style: "cancel"
},
{ text: "???", onPress: () => console.log("OK Pressed") }
],
{ cancelable: false }
);
}
onRowOpen =() => {
console.log('cfdfdf')
}
render() {
return (
<View style={styles.container}>
<Header searchBar rounded>
<Item>
<Icon name="ios-search" />
<Input placeholder="Search" onChangeText={this.searchData} />
<Icon name="ios-people" />
</Item>
<Button transparent>
<Text>Search</Text>
</Button>
</Header>
<SwipeListView
useFlatList
extraData={this.state}
data={this.state.filteredData && this.state.filteredData.length > 0 || this.state.lety == true ? this.state.filteredData : this.state.data}
keyExtractor={item => item.Id.toString()}
renderItem={(data, rowMap) => (
<Animated.View
style={[
styles.rowFront,
data.index % 2 === 0 && { backgroundColor: 'white' },
{ height: 100 }
]}
>
<Text style={{position: 'absolute', top: 35 , fontSize:20}}>
{data.item.Word}
</Text>
</Animated.View>
)}
renderHiddenItem={ (data, rowMap) => (
<View style={styles.rowBack}>
<Text style={{fontSize:20}}>{data.item.Meaning}</Text>
<TouchableOpacity style={[styles.backRightBtn, styles.backRightBtnLeft]} onPress={this.editItem(data.item.Id)}>
<Icon name='md-information-circle-outline' />
</TouchableOpacity>
<TouchableOpacity style={[styles.backRightBtn, styles.backRightBtnRight]} onPress={this.deleteItem(data.item.Id)}>
<Icon name='trash-outline' />
</TouchableOpacity>
</View>
)}
leftOpenValue={90}
rightOpenValue={-150}
onEndReached={this.handleLoadMore}
onEndReachedThreshold={0.5}
initialNumToRender={8}
ItemSeparatorComponent={this.renderSeparator}
ListFooterComponent={this.renderFooter}
onRefresh={this.handleRefresh}
refreshing={this.state.refreshing}
/>
<ActionSheet ref={(c) => { this.actionSheet = c; }} />
</View>
);
}
}
export default App
const styles = StyleSheet.create({
container: {
backgroundColor: 'white',
flex: 1,
//paddingTop: 50,
},
backTextWhite: {
color: '#FFF'
},
rowFront: {
alignItems: 'center',
backgroundColor: '#CCC',
justifyContent: 'center',
},
rowBack: {
alignItems: 'center',
backgroundColor: 'green',
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
paddingLeft: 15,
},
backRightBtn: {
alignItems: 'center',
bottom: 0,
justifyContent: 'center',
position: 'absolute',
top: 0,
width: 75
},
backRightBtnLeft: {
backgroundColor: 'blue',
right: 75
},
backRightBtnRight: {
backgroundColor: 'red',
right: 0
},
});
The list works properly and comes data but whenever I scroll down or up it doesn't work anymore. Please help me
If you are in mindset to change your package, then you can try react-native-snap-carousel, perfect for your requirement. Thanks
import React, { Component } from 'react';
import {
SafeAreaView,
Text,
View,
Image,
ScrollView,
StyleSheet,
StatusBar,
TextInput,
TouchableOpacity
} from 'react-native';
export default class LoginFrom extends React. Component {
state = {
isLoading: false,
strEmail: "test#example.com", isEmailValid: true, errMsgEmail: "",
strPassword: "test#123", isPasswordValid: true, errMsgPassword: "",
strErrMsg: ""
}
login() {
setTimeout(() => {
fetch("url", {
method: 'POST',
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify({
'email': this.state.strEmail,
'password': this.state.strPassword
})
}).then((response) => {
if (response.status == 200) {
return response.json()
} else {
return null
}
}).then((responseJson) => {
console.log(responseJson);
if (responseJson != null) {
this.setState({
strErrMsg: ""
})
} else {
this.setState({
strErrMsg: "Email and password does not match."
})
}
})
}, 100);
}
txtEmailChangeHangler = (val) => {
this.setState({
strEmail: val.trim()
})
}
txtPasswordChangeHangler = (val) => {
this.setState({
strPassword: val.trim()
})
}
render() {
return (
<View style={styles.container}>
<TextInput style={styles.inputbox}
onSubmitEditing={() => { this.secondTextInput.focus(); }}
underlineColorAndroid='rgba(0,0,0,0)'
placeholder='Email'
selectionColor='#fff'
value={this.state.strEmail}
onChangeText={this.txtEmailChangeHangler}
keyboardType='email-address' />
<TextInput
secureTextEntry={true}
style={styles.inputbox}
underlineColorAndroid='rgba(0,0,0,0)'
placeholder='password'
onChangeText={this.txtPasswordChangeHangler}
value={this.state.strPassword}
ref={(input) => { this.secondTextInput = input; }} />
<TouchableOpacity onPress={this.login} style={styles.button}>
<Text style={styles.buttontext}>{this.props.type}</Text>
</TouchableOpacity>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: '#D3EDFA',
flexGrow: 1,
alignItems: 'center',
justifyContent: 'center'
},
inputbox: {
width: 300,
backgroundColor: 'rgba(255,255,255,1)',
borderRadius: 25,
paddingHorizontal: 16,
marginVertical: 10
},
button: {
width: 300,
backgroundColor: '#ED6825',
borderRadius: 25,
paddingVertical: 16,
marginVertical: 10
},
buttontext:
{
fontSize: 16,
color: '#ffffff',
fontWeight: '100',
textAlign: 'center',
paddingHorizontal: 16,
}
})
Just try replacing login function with fat arrow function
login() {
// your code here
}
to
login = () => {
// your code here
}
hope it helps, this is done because fat arrow functions implicty binds this keyword
i am new to react native following a tutorial. I noticed there is no consistency of buttons between android and iOS so i thought i'd try react-native-paper library.
however, after importing the button from react-native-paper i am having problems changing the color of the button. the color is a constant color as in the image provided how the color looks
how can i manipulate the color? also is there a better library to use for button consistency between android and iOS ?
thanks
here is the code :
// import stuff
import React from 'react';
import { View, Text, TextInput, TouchableOpacity } from 'react-native';
import {
Provider as PaperProvider,
DarkTheme,
DefaultTheme,
Button
} from 'react-native-paper';
// import { Button } from 'react-native-paper';
//create stuff
class App extends React.Component {
state = {
text: "",
todo: []
}
addTodo = () => {
var newTodo = this.state.text
var arr = this.state.todo
arr.push(newTodo)
this.setState({ todo: arr, text: "" })
}
deleteTodo = (t) => {
var arr = this.state.todo;
var pos = arr.indexOf(t);
arr.splice(pos, 1);
this.setState({ todo: arr });
}
renderTodos = () => {
return this.state.todo.map(t => {
return (
<TouchableOpacity key={t}>
<Text
style={styles.todo}
onPress={() => { this.deleteTodo(t) }}
>{t}</Text>
</TouchableOpacity>
)
})
}
render() {
return (
<PaperProvider>
<View style={styles.wholeStyle}>
<View style={styles.viewStyle}>
<Text style={styles.header}>Notes App</Text>
<TextInput
style={styles.inputStyle}
onChangeText={(text) => this.setState({ text })}
value={this.state.text}
/>
<Button
onPress={this.addTodo}
mode='contained'
backgroundColor='black'
>Todo</Button>
{this.renderTodos()}
</View>
</View>
</PaperProvider>
)
}
}
const styles = {
wholeStyle: {
flex: 1,
backgroundColor: '#0288D1'
// backgroundColor: 'red'
},
viewStyle: {
alignItems: 'center',
justifyContent: 'center',
margin: 10,
marginTop: 30,
},
inputStyle: {
alignSelf: 'stretch',
height: 40,
borderColor: "white",
borderWidth: 1
},
header: {
fontSize: 40,
color: 'white',
fontWeight: 'bold'
},
todo: {
fontSize: 18,
color: 'white'
}
}
//export stuff
export default App;
from docs, labelStyle
UPDATE: thanks for the feed back, I managed to correct my code , adding a button using the property labelStyle to style the text inside the button, here is the final code , setting the button to black background and red text :
// import stuff
import React from 'react';
import { View, Text, TextInput, TouchableOpacity } from 'react-native';
import {
Provider as PaperProvider,
DarkTheme,
DefaultTheme,
Button
} from 'react-native-paper';
// import { Button } from 'react-native-paper';
//create stuff
class App extends React.Component {
state = {
text: "",
todo: []
}
addTodo = () => {
var newTodo = this.state.text
var arr = this.state.todo
arr.push(newTodo)
this.setState({ todo: arr, text: "" })
}
deleteTodo = (t) => {
var arr = this.state.todo;
var pos = arr.indexOf(t);
arr.splice(pos, 1);
this.setState({ todo: arr });
}
renderTodos = () => {
return this.state.todo.map(t => {
return (
<TouchableOpacity key={t}>
<Text
style={styles.todo}
onPress={() => { this.deleteTodo(t) }}
>{t}</Text>
</TouchableOpacity>
)
})
}
render() {
return (
<PaperProvider>
<View style={styles.wholeStyle}>
<View style={styles.viewStyle}>
<Text style={styles.header}>Notes App</Text>
<TextInput
style={styles.inputStyle}
onChangeText={(text) => this.setState({ text })}
value={this.state.text}
/>
<Button
onPress={this.addTodo}
mode='contained'
color='black'
labelStyle={styles.button}
>Todo</Button>
{this.renderTodos()}
</View>
</View>
</PaperProvider>
)
}
}
const styles = {
wholeStyle: {
flex: 1,
backgroundColor: '#0288D1'
// backgroundColor: 'red'
},
viewStyle: {
alignItems: 'center',
justifyContent: 'center',
margin: 10,
marginTop: 30,
},
inputStyle: {
alignSelf: 'stretch',
height: 40,
borderColor: "white",
borderWidth: 1
},
header: {
fontSize: 40,
color: 'white',
fontWeight: 'bold'
},
todo: {
fontSize: 18,
color: 'white'
},
button: {
color: 'red'
},
}
//export stuff
export default App;
Looking at react-native-paper Docs looks like backgroundColor is not a valid prop to pass.
The prop to use is just color so it would be:
color:{ "black" }
I think according to react-native-paper Docs , You can add custom styles in the style prop. define some style object in your stylesheet and asign that object in your button.
<Button
onPress={this.addTodo}
mode='contained'
style={styles.mybuttonstyles}>Todo
</Button>
//In Your Styles Section,
const styles = StyleSheet.create({
mybuttonstyles:{
backgroundColor:'black'
// all more styles you would like
}
i think this should work. in react-native-elements buttons, its similar. (instead of style, you should provide your style object buttonStyle for custom styles.) also make sure you create a Stylesheet and make sure to import that Stylesheet like
import { View, Text,StyleSheet } from 'react-native';
I have a small API front end that works properly, except updating the ListView after an _onPress method is called to update the api data.
import React, {Component} from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
ListView,
Image,
RefreshControl,
TouchableOpacity
} from 'react-native';
import Header from './Header';
export default class api extends Component {
constructor(props) {
super(props);
this._onPress = this._onPress.bind(this);
var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
this.state = {
refreshing: false,
pageNumber: 0,
flightsData: ds.cloneWithRows([]),
};
}
fetchFlightsData() {
/*removed for brevity*/
}
_onPress() {
this.setState({refreshing: true});
this.setState({pageNumber: this.state.pageNumber + 1});
this.fetchFlightsData();
this.setState({refreshing: false});
};
_onRefresh() {
this.setState({pageNumber: 0});
this.fetchFlightsData()
}
componentDidMount() {
this.fetchFlightsData();
}
render() {
return (
<ListView
renderHeader={() => <Header />}
renderFooter={() => this.renderFooter() }
dataSource={this.state.flightsData}
renderRow={this.renderRow}
style={styles.container}
refreshControl={
<RefreshControl
refreshing={this.state.refreshing}
onRefresh={this._onRefresh.bind(this)}
/>
}
/>
);
}
renderFooter() {
return (
<View style={styles.container}>
<TouchableOpacity style={styles.button} onPress={() => this._onPress()}>
<Text style={styles.text}>Load More</Text>
</TouchableOpacity>
</View>
);
}
renderRow(rowData) {
return (
/*removed for brevity*/
);
}
}
const styles = StyleSheet.create({
container: {
backgroundColor: '#f2f2f2',
},
thumb: {
backgroundColor: '#ffffff',
marginBottom: 5,
elevation: 1
},
img: {
height: 300
},
txt: {
margin: 10,
fontSize: 16,
textAlign: 'left'
},
button: {
borderColor: '#8E8E8E',
borderWidth: StyleSheet.hairlineWidth,
paddingHorizontal: 20,
paddingVertical: 10,
borderRadius: 5,
},
});
AppRegistry.registerComponent('api', () => api);
When the onPress method is called, it refreshes the data as expected, but does not update the ListView, that is until you press the button the second time, which it displays the new data from the first press.
The _onRefresh() method works exhibits similar behavior.
setState does not change state immediately, you must use the optional second parameter if you want to do something after the state has been updated:
_onPress() {
this.setState({ refreshing: true, pageNumber: this.state.pageNumber + 1 },
() => this.fetchFlightsData());
this.setState({refreshing: false}); //This part should probably go inside fetchFlightsData once you retrieve the data.
};