Invariant Violation: "elevation" is not a valid style property - react-native

Iam trying to put some shadow and elevation to my card, but it show an error which is "elevation" is not a valid style property...... When i added the style elevation this error will appear insead of the elevation
/**
* Created by Yasi Ahmed on 05-12-2015.
*/
'use strict';
var React = require('react-native');
var BloggerApi = require('./BloggerApi');
var HTMLView = require('react-native-htmlview');
var striptags = require('striptags');
var moment = require('moment');
var {
ListView,
StyleSheet,
Text,
View,
TouchableOpacity,
} = React;
var PostListView = React.createClass({
getInitialState: function () {
return {
dataSource: new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2,
}),
loaded: false,
};
},
fetchData: function () {
var items = require("./dummy/posts.json");
this.setState({
dataSource: this.state.dataSource.cloneWithRows(items.items),
loaded: true
});
/*
BloggerApi.fetchPosts()
.then((responseData) => {
this.setState({
dataSource: this.state.dataSource.cloneWithRows(responseData.items),
loaded: true
});
})
.done();
*/
},
componentDidMount: function () {
this.fetchData();
},
render: function () {
if (!this.state.loaded) {
return this.renderLoadingView();
} else {
console.log(this.state)
}
return (
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderPostItem}
style={styles.listView}
/>
);
},
/*
<CoreShadowView cornerRadius={4} shadowRadius={4} style={[{backgroundColor: '#FFFFFF'}]}>
<Text>D. 完全知道</Text>
</CoreShadowView>
*/
renderPostItem: function (post) {
return (
<TouchableOpacity>
<View style={styles.rightContainer}>
<Text style={styles.title}>{post.title}</Text>
<View style={styles.content}>
<Text>
{striptags(post.content).substring(0, 100)}........
</Text>
</View>
<View style={styles.bottomContainer}>
<Text style={styles.date}>{moment(post.published).format("MMM Do YY, h:mm a")}</Text>
<Text style ={styles.read_more}>Read more...</Text>
</View>
</View>
</TouchableOpacity>
);
},
renderLoadingView: function () {
return (
<View style={styles.container}>
<Text>
Loading posts...
</Text>
</View>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF'
},
rightContainer: {
borderWidth: .5,
borderColor: '#000',
paddingLeft: 15,
paddingRight: 15,
flex: 1,
marginBottom:5,
marginLeft:5,
marginRight:5,
borderRadius: 4,
borderTopLeftRadius: 3,
borderTopRightRadius: 3,
borderBottomLeftRadius: 3,
borderBottomRightRadius: 3,
shadowColor: '#000',
shadowOffset: {width: 2, height: 2},
shadowOpacity: 1,
shadowRadius: 5,
elevation: 10
},
bottomContainer: {
flexDirection: 'row',
paddingLeft: 15
},
title: {
fontSize: 20,
marginBottom: 8,
textAlign: 'center'
},
date: {
paddingLeft: 25,
fontSize: 14,
color: '#2196f3',
marginBottom: 8
},
read_more: {
paddingRight: 50,
textAlign: 'right',
fontSize: 14,
color: '#2196f3'
},
content: {
paddingLeft: 25,
height: 100,
paddingRight: 25
},
listView: {
paddingTop: 20,
backgroundColor: '#F5FCFF'
}
});
module.exports = PostListView;

I'm guessing that #HarryMoreno believed that it wasn't a supported property because at the time it hadn't made it into the documentation. However, it is a supported property as of 0.16 for Views, as can be seen here: https://facebook.github.io/react-native/docs/view.html#style.
Don't know of course if you're still running into this error after updating to the latest build (currently 0.17) but if so might it be because you're building for iOS? The documentation doesn't say this is an Android-only property (in fact it hardly says anything at all :P ) but I believe the original intent was to implement shadows on Android as per this discussion: https://github.com/facebook/react-native/pull/4180

elevation is not a supported css style in React Native. For a list of supported properties see https://facebook.github.io/react-native/docs/style.html#supported-properties

Related

React Native Flatlist not rendering but show ActivityIndicator

My React Native Flatlist is not rendering. It does not show any error nor does the app crash. It just shows an ActivityIndicator
home.js
export default function Second({navigation}) {
const [loca, setLoca] = useState([]);
const Get = async () => {
const myDoc = collection(db, 'users');
const querySnapshot = await getDocs(myDoc);
querySnapshot.forEach(doc => {
console.log(doc.id, ' => ', doc.data());
setLoca({
id: doc.id,
fname: doc.data().fname,
});
console.log(loca);
});
};
const Logout = () => {
signOut(auth)
.then(() => {
// Sign-out successful.
console.log('log out');
navigation.navigate('Login');
})
.catch(error => {
// An error happened.
console.log(error);
});
};
useEffect(() => {
Get();
}, []);
const renderItemm = ({item}) => <Comp title={item.fname} />;
return (
<View style={styles.conn}>
<ImageBackground source={image} resizeMode="cover" style={{flex: 1}}>
<View style={{paddingHorizontal: 15}}>
<View style={styles.box}>
<View style={{justifyContent: 'space-between'}}>
<Text>HOME</Text>
<TouchableOpacity style={styles.box1} onPress={Logout}>
<Text>dd</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.box1}
onPress={() => navigation.navigate('Third')}></TouchableOpacity>
</View>
</View>
{loca.length > 0 ? (
<FlatList
data={loca}
renderItem={renderItemm}
keyExtractor={item => item.id}
/>
) : (
<ActivityIndicator />
)}
</View>
</ImageBackground>
</View>
);
}
const styles = StyleSheet.create({
conn: {
//flexDirection: 'column',
flex: 1,
},
tt: {
color: 'white',
backgroundColor: '#4DA69B',
fontSize: 24,
width: 80,
height: 80,
borderRadius: 40,
alignItems: 'center',
},
box: {
marginTop: 10,
flexWrap: 'wrap',
flexDirection: 'row',
},
end: {
//justifyContent: 'space-between',
alignItems: 'flex-end',
marginBottom: 10,
},
box1: {
width: 48,
height: 48,
borderRadius: 24,
backgroundColor: '#67BE92',
marginTop: 10,
marginLeft: 10,
alignItems: 'flex-end',
},
boxxx: {
backgroundColor: '#f9c2ff',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
},
});
comp.js
const comp = (props) => {
return (
<View style={styles.conn}>
<View style={styles.box}>
<Text>{props.title}</Text>
</View>
</View>
);
};
export default comp;
const styles = StyleSheet.create({
conn: {
flex: 1,
flexDirection: 'row',
justifyContent: 'space-between',
},
tt: {
color: 'white',
backgroundColor: '#4DA69B',
fontSize: 24,
width: 80,
height: 80,
borderRadius: 40,
alignItems: 'center',
},
box: {
flex: 1,
marginTop: 10,
borderRadius: 10,
width: '100%',
height: 115,
borderWidth: 1,
borderColor: '#67BE92',
backgroundColor: 'white',
flexDirection: 'row',
},
end: {
alignItems: 'flex-end',
marginBottom: 10,
},
box1: {
width: 48,
height: 48,
borderRadius: 24,
backgroundColor: '#67BE92',
marginTop: 10,
marginLeft: 10,
},
});
i dont slove this plobem it show ActivityIndicator not show flatlist I use my firebase data and console.lod(loca) show that data but flatlist not show
solve my flatlist and show in my project
The data passed to the FlatList should always be an array. So you should edit your code as follow:
const Get = async () => {
const myDoc = collection(db, 'users');
const querySnapshot = await getDocs(myDoc);
querySnapshot.forEach(doc => {
console.log(doc.id, ' => ', doc.data());
// I changed the below
setLoca([...loca, {
id: doc.id,
fname: doc.data().fname,
}]);
console.log(loca);
});
};
We are looping over querySnapshot, so this syntax "setLoca([...loca, {..}])" keeps the already saved data while looping.

React Native - Is there any best way to give the style `borderRadius` each button?

I have created three buttons using map, and the 1st and the 3rd buttons have borderRadius on the side.
This is what it looks like :
Even though I anyways displayed the buttons as expected, but I feel like this code should be better than I did. Plus, I am not so sure if it is okay to map the buttons in this way..
My code below :
const styles = StyleSheet.create({
row: {
flexDirection: 'row',
justifyContent: 'flex-end',
marginRight: 15,
marginTop: 15,
},
btnWrap: {
width: 50,
height: 24,
backgroundColor: colors.white_two,
borderWidth: 0.5,
borderColor: colors.very_light_pink_five,
justifyContent: 'center',
alignItems: 'center',
},
textStyle: {
fontSize: 10,
fontWeight: 'normal',
color: colors.very_light_pink_five,
},
btnLeft: {
borderTopLeftRadius: 6,
borderBottomLeftRadius: 6,
},
btnRight: {
borderTopRightRadius: 6,
borderBottomRightRadius: 6,
},
btnMiddle: {
borderLeftWidth: 0,
borderRightWidth: 0,
},
selected: {
backgroundColor: colors.black,
},
selectedText: {
color: colors.white_two,
},
});
const pointType = ['one', 'two', 'three'];
const MypagePoint = ({ totalPoint }) => {
const [btnClicked, setBtnClicked] = useState(null);
return (
<View style={[styles.container]}>
<View style={[styles.row, { marginBottom: 15 }]}>
{pointType.map((type, index) => (
<TouchableOpacity
style={[
styles.btnWrap,
btnClicked === index && styles.selected,
// This is the part I doubt
index === 0 && styles.btnLeft,
index === 1 && styles.btnMiddle,
index === 2 && styles.btnRight,
]}
onPress={() => setBtnClicked(index)}
>
<Text
style={[
styles.textStyle,
btnClicked === index && styles.selectedText,
]}
>
{type}
</Text>
</TouchableOpacity>
))}
</View>
</View>
);
};
Would you let me know the best way to code?
Old Solution: Use ternary operator instead.
Updated: Create a helper function and use the rounded corner styling only for the first and last buttons.
Working Example: Expo Snack
import React, { useState, useEffect } from 'react';
import {
Text,
View,
StyleSheet,
TouchableOpacity,
FlatList,
} from 'react-native';
import Constants from 'expo-constants';
const styles = StyleSheet.create({
row: {
flexDirection: 'row',
justifyContent: 'flex-end',
marginRight: 15,
marginTop: 15,
},
btnWrap: {
width: 50,
height: 24,
backgroundColor: 'white',
borderWidth: 1,
borderColor: 'pink',
justifyContent: 'center',
alignItems: 'center',
margin: -2,
},
textStyle: {
fontSize: 10,
fontWeight: 'normal',
color: 'pink',
},
btnLeft: {
borderTopLeftRadius: 6,
borderBottomLeftRadius: 6,
},
btnRight: {
borderTopRightRadius: 6,
borderBottomRightRadius: 6,
},
selected: {
backgroundColor: 'black',
},
selectedText: {
color: 'white',
},
});
const pointType = ['one', 'two', 'three', 'four', 'five', 'six'];
export default MypagePoint = ({ totalPoint }) => {
const [btnClicked, setBtnClicked] = useState(null);
const buttonStyle = (index) => {
if (index === 0) return styles.btnLeft;
else if (index === pointType.length - 1) return styles.btnRight;
};
return (
<View style={[styles.container]}>
<View style={[styles.row, { marginBottom: 15 }]}>
{pointType.map((type, index) => (
<Button
index={index}
btnClicked={btnClicked}
buttonStyle={buttonStyle}
setBtnClicked={setBtnClicked}
type={type}
/>
))}
</View>
</View>
);
};
const Button = ({ index, btnClicked, buttonStyle, setBtnClicked, type }) => {
return (
<TouchableOpacity
style={[
styles.btnWrap,
btnClicked === index && styles.selected,
buttonStyle(index),
]}
onPress={() => setBtnClicked(index)}>
<Text
style={[styles.textStyle, btnClicked === index && styles.selectedText]}>
{type}
</Text>
</TouchableOpacity>
);
};

React Native - The Color of TouchableOpacity Button Should Change Without Map

I have only two buttons, and I want their backgroundColor to be changed when pressing. I don't want to use map as there are only two buttons. I have tried some ways to approach what I expect, but I am at a loss what to do.
RoundedButtonSet :
const styles = StyleSheet.create({
container: {
marginBottom: 20,
},
});
const RoundedButtonSet = ({ firstBtn, secondBtn, contentStyle }) => {
return (
<View style={[styles.container, contentStyle]}>
<RoundedButtons firstBtn={firstBtn} secondBtn={secondBtn} />
</View>
);
};
RoundedButtons :
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
marginHorizontal: 15,
height: 40,
alignItems: 'center',
},
btn: {
flex: 1,
borderWidth: 1,
borderColor: colors.very_light_pink,
borderRadius: 6,
paddingVertical: 13,
height: 40,
},
btnTextStyle: {
fontSize: 12,
fontWeight: 'normal',
color: colors.very_light_pink_five,
textAlign: 'center',
},
left: {
borderTopRightRadius: 0,
borderBottomRightRadius: 0,
borderColor: colors.very_light_pink,
},
right: {
borderTopLeftRadius: 0,
borderBottomLeftRadius: 0,
borderLeftWidth: 0,
},
backgroundColor: {
backgroundColor: colors.iris,
},
textColor: {
color: colors.white_two,
},
});
const RoundedButtons = ({ firstBtn, secondBtn, contentStyle, onPress }) => {
const [isClicked, setIsClicked] = useState(true);
return (
<View style={[styles.container, contentStyle]}>
<TouchableOpacity
style={[styles.btn, styles.left, isClicked && styles.backgroundColor]}
onPress={() => setIsClicked(!isClicked)}
>
<Text style={[styles.btnTextStyle, isClicked && styles.textColor]}>
{firstBtn}
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[styles.btn, styles.right]}
onPress={() => setIsClicked()}
>
<Text style={[styles.btnTextStyle]}>{secondBtn}</Text>
</TouchableOpacity>
</View>
);
};
RoundedButtons.propTypes = {
firstBtn: Text.propTypes,
secondBtn: Text.propTypes,
};
export default RoundedButtons;
Should I give index directly to each button? I have got this idea, but the problem is I have no idea how to access..
You can have a simple state to keep track of which button is pressed and use that to apply styles conditionally.
Here is the working example: Expo Snack
import React, { useState } from 'react';
import { Text, View, StyleSheet, TouchableOpacity } from 'react-native';
import Constants from 'expo-constants';
// You can import from local files
import AssetExample from './components/AssetExample';
// or any pure javascript modules available in npm
import { Card } from 'react-native-paper';
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
marginHorizontal: 15,
height: 40,
alignItems: 'center',
},
btn: {
flex: 1,
borderWidth: 1,
borderColor: 'pink',
borderRadius: 6,
paddingVertical: 13,
height: 40,
},
btnTextStyle: {
fontSize: 12,
fontWeight: 'normal',
color: 'pink',
textAlign: 'center',
},
left: {
borderTopRightRadius: 0,
borderBottomRightRadius: 0,
borderColor: 'pink',
},
right: {
borderTopLeftRadius: 0,
borderBottomLeftRadius: 0,
borderLeftWidth: 0,
},
backgroundColor: {
backgroundColor: 'black',
},
textColor: {
color: 'white',
},
});
const RoundedButtons = ({ firstBtn, secondBtn, contentStyle, onPress }) => {
const [clickedBtn, setIsClicked] = useState(null);
React.useEffect(() => {
console.log(clickedBtn);
}, [clickedBtn]);
return (
<View style={[styles.container, contentStyle]}>
<TouchableOpacity
style={[
styles.btn,
styles.left,
clickedBtn == 1 && styles.backgroundColor,
]}
onPress={() => setIsClicked(1)}>
<Text
style={[styles.btnTextStyle, clickedBtn == 1 && styles.textColor]}>
firstBtn
</Text>
</TouchableOpacity>
<TouchableOpacity
style={[
styles.btn,
styles.right,
clickedBtn == 2 && styles.backgroundColor,
]}
onPress={() => setIsClicked(2)}>
<Text
style={[styles.btnTextStyle, clickedBtn == 2 && styles.textColor]}>
secondBtn
</Text>
</TouchableOpacity>
</View>
);
};
RoundedButtons.propTypes = {
firstBtn: Text.propTypes,
secondBtn: Text.propTypes,
};
export default RoundedButtons;

Updates State when SectionList has finished rendering

I have a sectionlist with an ActivityIndicator at the footer. The ActivityIndicator doesn't go away even after the list has rendered every item. The data is local data.
I do know that I have to use React Hook, so I created _handleLoadMore() to update the state, but I don't know how to detect once the list has come to the end.
This is my code
import React, {useState, useEffect} from 'react';
import {
View,
Text,
StyleSheet,
SectionList,
ActivityIndicator,
} from 'react-native';
import {SafeAreaView} from 'react-native-safe-area-context';
export default function TransactionHistoryList({data}: {data: any}) {
const [loadMore, setLoadMore] = useState('true')
const _handleLoadMore = () => {
//what to put here
}
const extractKey = ({
id,
}: {
id: any;
name: any;
accountNumber: any;
type: any;
amount: any;
}) => id;
const renderSeparator = () => {
return (
<View
style={{
height: 1,
width: '94%',
backgroundColor: '#000',
alignSelf: 'center',
}}
/>
);
};
const footerComponent = () => {
if (!_handleLoadMore) return null;
return (
<View
style={{
position: 'relative',
paddingVertical: 20,
borderTopWidth: 1,
marginTop: 10,
marginBottom: 10,
}}>
<ActivityIndicator
animating
size="small"
color="#CED0CE"
hidesWhenStopped={true}
/>
</View>
);
};
return (
<SafeAreaView>
<View style={styles.container}>
<Text style={styles.transactionhistory}>Transaction History</Text>
<SectionList
contentContainerStyle={{paddingBottom: 500}}
maxToRenderPerBatch={7}
onEndReachedThreshold={2}
updateCellsBatchingPeriod={4000}
ItemSeparatorComponent={renderSeparator}
sections={data}
renderSectionHeader={({section}) => {
return <Text style={styles.date}>{section.title}</Text>;
}}
renderItem={({item}) => {
return (
<View style={styles.item}>
<Text>
<View>
<Text style={styles.name}>{item.name}</Text>
<Text style={styles.accountNumber}>
{item.accountNumber}
</Text>
</View>
</Text>
<View style={styles.amountContainer}>
<Text
style={[
item.type == 'in' ? styles.moneyIn : styles.moneyOut,
]}>
{item.amount}
</Text>
</View>
</View>
);
}}
ListFooterComponent= {footerComponent}
keyExtractor={extractKey}
/>
</View>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
marginLeft: 20,
marginRight: 20,
marginTop: 120,
flex: -200,
//paddingBottom: 10
},
transactionhistory: {
fontWeight: 'bold',
fontSize: 18,
paddingBottom: 10,
paddingLeft: 25,
},
item: {
flexDirection: 'row',
justifyContent: 'space-between',
marginRight: 20,
marginLeft: 25,
paddingBottom: 10,
paddingTop: 10,
},
date: {
padding: 10,
marginBottom: 15,
backgroundColor: '#e0e0e0',
fontFamily: 'OpenSans-Bold',
fontSize: 15,
paddingLeft: 25,
},
name: {
fontSize: 14,
fontFamily: 'OpenSans-SemiBold',
},
accountNumber: {
fontSize: 12,
fontFamily: 'OpenSans-Regular',
},
amountContainer: {
paddingTop: 8,
},
moneyIn: {
color: '#689f38',
letterSpacing: 0.8,
fontSize: 16,
fontFamily: 'OpenSans-SemiBold',
},
moneyOut: {
color: '#b71c1c',
letterSpacing: 0.8,
fontSize: 16,
fontFamily: 'OpenSans-SemiBold',
},
loading: {
color: '#CED0CE',
},
});
section-list support on-scroll event and you can can hide/show activity-indicator feature quite smoothly with on scroll
Example:
const isCloseToBottom = ({layoutMeasurement, contentOffset, contentSize}) => {
const paddingToBottom = 20;
return layoutMeasurement.height + contentOffset.y >=
contentSize.height - paddingToBottom;
};
<SectionList
contentContainerStyle={{paddingBottom: 500}}
maxToRenderPerBatch={7}
onEndReachedThreshold={2}
onScroll={({nativeEvent}) => {
if (isCloseToBottom(nativeEvent)) {
if(!this.state.fetching_status){
//what you want to do when the screen reached end of screen
//console.log or something usefull
}
}
}}
.../>
I think it is possible to use onEndReached prop of SectionList in your case https://reactnative.dev/docs/sectionlist#onendreached
That is the correct place to write your logic to load next "page" of your items

Modal component is undefined in react-native 0.10.1

I'm trying to use the Modal component from react-native and it's value is undefined. Here is the component I'm trying to build:
'use strict';
var React = require('react-native');
var {
Modal,
StyleSheet,
Text,
View,
TouchableHighlight
} = React;
var Button = React.createClass({
getInitialState() {
return {
active: false,
};
},
onHighlight: function() {
this.setState({active: true});
},
onUnhighlight: function() {
this.setState({active: false});
},
render: function() {
var colorStyle = {
color: this.state.active ? '#fff' : '#000',
};
return (
<TouchableHighlight
onHideUnderlay={this.onUnhighlight}
onPress={this.props.onPress}
onShowUnderlay={this.onHighlight}
style={[styles.button, this.props.style]}
underlayColor='#a9d9d4'>
<Text style={[styles.buttonText, colorStyle]}>{this.props.children}</Text>
</TouchableHighlight>
);
}
});
var ModalBox = React.createClass({
getInitialState: function() {
return {
animated: true,
modalVisible: true,
transparent: false,
};
},
setModalVisible: function(visible) {
this.setState({modalVisible: visible});
},
render: function() {
var modalBackgroundStyle = {
backgroundColor: this.state.transparent ? 'rgba(0, 0, 0, 0.5)' : '#f5fcff',
};
var innerContainerTransparentStyle = this.state.transparent
? {backgroundColor: '#fff', padding: 20}
: null;
return (
<View>
<Modal
animated={this.state.animated}
transparent={this.state.transparent}
visible={this.state.modalVisible}>
<View style={[styles.container, modalBackgroundStyle]}>
<View style={[styles.innerContainer, innerContainerTransparentStyle]}>
<Text>This modal was presented {this.state.animated ? 'with' : 'without'} animation.</Text>
</View>
<Button
onPress={this.setModalVisible.bind(this, false)}
style={styles.modalButton}>
Close
</Button>
</View>
</Modal>
</View>
);
},
});
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
padding: 20,
},
innerContainer: {
borderRadius: 10,
},
button: {
borderRadius: 5,
flex: 1,
height: 44,
justifyContent: 'center',
overflow: 'hidden',
},
buttonText: {
fontSize: 18,
margin: 5,
textAlign: 'center',
},
button: {
borderRadius: 5,
flex: 1,
height: 44,
justifyContent: 'center',
overflow: 'hidden',
},
buttonText: {
fontSize: 18,
margin: 5,
textAlign: 'center',
},
modalButton: {
marginTop: 10,
},
modalButton: {
marginTop: 10,
},
});
module.exports = ModalBox;
And this is the error I get when I add <ModalBox/> component to my index.ios.js:
Error: Invariant Violation: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.
I don't where you're requiring the modal module.
Make sure you npm install and include the below line in your js file.
Upgrading to react-native 0.11.0 fixed the problem for me