Inheritance In React Native Style Sheets - react-native

So in a regular cascading style sheet we can inherit from other styles doing so:
.myStyle .temp {
height: 100px,
width: 80px,
}
My question is:
is there a way for me to do this in react native. I have tried a few different ways but cannot seem to get it to work. Some of the methods in which I have tried are as follows:
// Example One
// Error Thrown: tempStyle is not defined.
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
...tempStyle,
},
tempStyle :{
backgroundColor: 'tomato'
}
});
The following also did not work for me, it did not throw any errors but simply did not work.
I set the style to be the tempStyle and it was basically a blank style sheet which does make sense as it probably points to nothing.
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
tempStyle :{
container :{
backgroundColor: 'tomato'
}
}
});
I know that we can reference multiple styles inside of the style property in a component using brackets.
<View style={[Styles.temp, Styles.tempTwo]} />
Is this the only way to accomplish this?

Your first idea does not work because you are trying to use a style object defined inside the create function of StyleSheet for another style object defined within the same create function. You cannot access them inside the create function.
However, you could define your styles in a plain JS object and then use the spread syntax in order to achieve pretty much the same thing.
Notice that a style is just a JS object after all.
Let us call this file styles.js.
// helper, keep local
const tempStyle = {
backgroundColor: 'tomato'
}
// we only want to use this style
// spread syntax works here
export const container = {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
...tempStyle,
}
export SomeOtherStyle = {
...tempStyle,
}
Then, we can use the above styles as usual.
import { container, SomeOtherStyle } from './styles.js'
...
<View style={[container, someOtherStyle]}></View>
Notice that we can make use of typescript here as well (if you are using it in your project).
// helper, keep local
const tempStyle: ViewStyle = {
backgroundColor: 'tomato'
}
// we only want to use this style
// spread syntax works here
export const container: ViewStyle = {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
...tempStyle,
}
export SomeOtherStyle: ViewStyle = {
...tempStyle,
}
Using typescript, you will have autocompletion and typechecking for your styles. Notice as well that there might be different styles for different types of components (e.g. TextStyle).

you can use the array notation:
<View style={[styles.container, styles.tempStyle]} />

Related

Using React Native StyleSheet like class of HTML

I had this question a long time ago. What if I use React Native StyleSheet like class of HTML? I really did use it. I have a lot of styles (names are based on Bootstrap Class Name).
import { StyleSheet } from "react-native";
const s = StyleSheet.create({
flex: { flex: 1 },
flexCenter: {
flex: 1,
alignItems: "center",
justifyContent: "center",
paddingVertical: 24,
},
p0: { padding: 0 },
p1: { padding: 4 },
p2: { padding: 8 },
textLight: { color: "#eee" },
fsLg: { fontSize: 18 },
... and so on
});
export default s;
Then, in components I use it like this.
<Text style={[s.fsLg, s.p2, s.textLight]}>Title</Text>
I do not use it anymore because I had a feeling it was a bad practice. I don't know surely. I have read official react native styling. They did not mention this is bad. How do anyone think?
When in doubt, check the docs: https://reactnative.dev/docs/style
The style prop can be a plain old JavaScript object. That's what we usually use for example code. You can also pass an array of styles - the last style in the array has precedence, so you can use this to inherit styles.
From the second paragraph. This is a recommended practice.

React Native: How to separate roles of developer and 'styler'

I'm working on a React Native app (initially only Web) where we need to separate the roles of developer and styler (i.e. the person responsible for styling the app). With traditional HTML development this is easily done through CSS. In other words, the developer assigns IDs and/or classes to HTML elements, allowing the CSS developer to get to work on the CSS files of the code-base.
Is it possible to do something similar in React Native? In other words, can we change the styles of the various elements of the user interface without needing to modify the code that generates the elements?
Yes. I think the style property of view is pretty similar to CSS, you just need to write a styles.js file separate from your view code. Then your "styler" just need to modify style attributes in that file instead of go into the main code.
Something like this:
Your styles.js
const styles = StyleSheet.create({
container: {
flexDirection: 'column',
backgroundColor: Colors.COLOR_BACKGROUND_LIGHT,
paddingBottom: normalize(50)
},
buttonContainer: {
flexDirection: 'column',
alignItems: 'center',
padding: Dimens.contentPadding
},
inputContainer: {
flexDirection: 'row',
height: normalize(30),
borderBottomWidth: 0.5,
alignItems: 'center',
borderBottomColor: Colors.COLOR_LIGHT_GREY,
},
});
Your index.js
import styles from ".....";
.....
.....
render() {
return (
<View style={styles.container}>
...
</View>
)
}
Hope that help ^^

Access to style property and change it

I am new to React-Native. Say I have a styleSheet contains style for a green button:
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#fff',
},
greenB:{
padding: 5,
height: 80,
width: 80,
borderRadius:160,
backgroundColor:'green',
}, ........
And for some reason I need to change that colour in my code.
render(){
....
const {container, greenB}=styles; //Not sure, how else can I define greenB?
greenB.backgroundColor='black';
return (
<View style={styles.container}>
<View style={styles.greenB} >
....
How can I access backgroundColor from greenB and change that?
I'm getting a TypeError "Attempted to assign to readonly property",
which is reasonable cause styles is a const.
tried to read about state management but not sure how to use it in this case.
React Native's StyleSheet.create is used for better performance and clean code, It caches the style ids to reduce the amount of data that goes through the bridge, so that is why you cannot alter it but only use it .
But there're many solutions, You can use simple javascript object and alter the values as you want.
For example:-
let Styles= {
Text:{
color:'blue'
}
}
Styles.Text.color= 'green'
<Text style={Styles.Text} > </Text>
More over, For dynamic styling i recommend using states instead of variables .

React native: Why does stylesheet.create return object with numbers and not styles?

I created styles, but sometimes I cannot use them because they return numbers:
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#FFFFFF'
},
moodSliderContainer: {
justifyContent: 'center',
alignItems: 'center',
width: '100%'
},
postListContainer: {
width: '100%',
height: '100%',
paddingBottom: 120
}
});
console.log(styles);
From React Native documentation - StyleSheet:
Performance:
Making a stylesheet from a style object makes it possible to refer to it by ID instead of creating a new style object every time.
It also allows to send the style only once through the bridge. All subsequent uses are going to refer an id (not implemented yet).
If you want to retrieve the actual style object, you can use StyleSheet.flatten(styles.container).
Stylesheet is used to reduce processing time and optimize performance.
The numbers are a reference to the original stylesheet object. You can check that numbers would be unique per stylesheet and there would be no overlap.
Therefore it makes sense to replace them with numbers. It is similar concept to Images path storage in react-native.
Probably for reusability. Consider the number as index in a table. For e.g., in your case, the container styles are stored at 219
BigStylesMap = {
219: {
flex: 1,
backgroundColor: '#FFFFFF'
}
...otherCachedStyles
}
If it finds some other place where similar styles are defined, it can refer to the same object.

Odd react-native issue with rendering

I'm currently trying to learn react-native and running into a problem after a tutorial. I followed the PropertyFinder tutorial on Ray Wenderlich's site, which went fine.
Breaking away now to start something on my own, I can't seem to get a page to render - and I keep running into the same exception which may be causing the page not to render (but I'm not entirely sure).
Here is the main app page, which is simply the navigator:
'use strict';
var React = require('react-native');
var WelcomePage = require('./WelcomePage');
var {
AppRegistry,
StyleSheet,
Text,
View,
} = React;
var MyApp = React.createClass({
render: function() {
return (
<React.NavigatorIOS style={styles.container}
initialRoute={{
title: 'Welcome',
component: WelcomePage
}}/>
);
}
});
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
}
});
AppRegistry.registerComponent('MyApp', () => MyApp);
And here's the welcome page:
'use strict';
var React = require('react-native');
var {
StyleSheet,
Text,
View,
Component
} = React;
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF'
},
textTitle: {
color: 'black',
fontSize: 35,
textAlign: 'center'
},
textSubs: {
color: 'black',
fontSize: 25,
textAlign: 'center'
}
});
class WelcomePage extends Component {
render() {
console.log('About to render welcome page');
return (
<View style={styles.container}>
<Text style={styles.textTitle}>
Welcome to MyApp!
</Text>
<Text style={styles.textSubs}>
Good Choice for an App
</Text>
<Text style={styles.textSubs}>
Going to start with setting up the App
</Text>
<Text style={styles.textSubs}>
Are you ready?
</Text>
</View>
);
}
}
module.exports = WelcomePage;
Now, the console logging comes out correctly with 'About to render welcome page', however the result I get is just a blank white window. If I use the chrome debugger, I do get an exception if a chose to Pause on Exceptions. The code snippet it pauses on is this:
/**
* Given a constructor can we call it without `new`?
*
* #param {function} Collection
*/
function isCallableWithoutNew(Collection) {
try {
Collection(); // <<<--- Here's where the exception seems to happen
} catch (e) {
return false;
}
return true;
}
If I go back to the tutorial project, it works just fine.
The only difference I can see is that when I initialized the tutorial project, the Animation library I pulled in did not have an 'Experimental' version (RCTAnimation), but with the new project I tried to start above, I have to use the Experimental version if I want it to work. Really though, I only tested that early on and am not pulling it in any longer (I don't need it yet).
I've also tried playing around a bit with the styles, but get the same result - and the same exception occurring.
Exception stack chrome shows is:
"TypeError: Constructor Map requires 'new'
at Map (native)
at isCallableWithoutNew (http://localhost:8081/index.ios.bundle:15407:5)
at shouldPolyfillES6Collection (http://localhost:8081/index.ios.bundle:15378:5)
at http://localhost:8081/index.ios.bundle:14500:8
at http://localhost:8081/index.ios.bundle:15095:3
at require (http://localhost:8081/index.ios.bundle:245:25)
at http://localhost:8081/index.ios.bundle:14288:11
at require (http://localhost:8081/index.ios.bundle:245:25)
at http://localhost:8081/index.ios.bundle:14131:11
at require (http://localhost:8081/index.ios.bundle:245:25)"
I want to say that looks like an API version issue or something?
Am I missing something obvious here?
Thanks for any help.
So this ended up being my styles on the 'index.ios.js' page.
I changed this:
var styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
}
});
To this:
var styles = StyleSheet.create({
container: {
flex: 1
}
});
And the view then rendered.
I guess I need to spend some time on figuring out how these styles layout components...
If anyone knows why the main NavigatorIOS pane would push content too far off to the right to be visible (which is what was happening) if the styles were set as they were originally, please let me know.
The culprits were:
'justifyContent'
'alignItems'
'backgroundColor' of course had no affect on the view rendering (I didn't add it back in but could without issue).