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

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 ^^

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.

Inheritance In React Native Style Sheets

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]} />

Use space-around without setting height value

I want to put 3 texts on the screen one on the top, one on the middle an one on the bottom. For this I thought about using the space-around property. This is my code
<Screen style={styles.container} backgroundColor={color.transparent}>
<View style={styles.playerContainer}>
<View><Text>text 1</Text></View>
<View><Text>text 2</Text></View>
<View><Text>text 3</Text></View>
</View>
</Screen>
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'blue'
},
playerContainer:{
flexDirection: 'column',
justifyContent: 'space-around',
alignItems: 'center',
backgroundColor: 'red',
}
});
This is not working as expected. It looks better is I set a height for playerContainer, but I am enable to calculate the right hight because of the navigation bar etc.. I just need to add three text in the container. I must calculate the hight of playerContainer or I am doing something wrong?
If you want the first entry to be at the start of the container, the second to be at the center, and the last to be at the end, you need justifyContent: 'space-between'. I found this article helpful when learning about flex in React Native https://blog.reactnativecoach.com/understanding-flex-in-react-native-b34dfb4b16d1

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.