Why should I use React native StyleSheet? - react-native

Why should I use this:
const styles = StyleSheet.create({
...
});
instead of this:
const styles = {
...
};
Properties that StyleSheet provides don't seem very needful to me.

Performance of rendering, better invalid prop values detection and better code quality.
When passing regular style objects into the StyleSheet.create(), the module will freeze the objects and assign each one an ID.
IDs enable optimizations through the bridge and memory in general
Some type or prop value validity checks of Stylesheet objects could warn you or help you fix some invalid style issue better than when using the normal object approach.
By moving styles away from the render function, you're making the code
easier to understand. Naming the styles is a good way to add meaning
to the low level components in the render function.
From what I've seen, both work (normal object, StyleSheet object) when setting the style of a component, even when you pass an array of objects.
Disadvantages when using the StyleSheet object:
1) you cannot make a comparison like this styles.myNiceComponent.backgroundColor === 'blue'
More details about this disadvantage here:
Why can't we check a style attribute of a react-native app?
2) Recomputing styles based on some criteria (like screen rotation) needs some additional infrastructure code to determine which styles to use. If you use simple objects they could be recomputed on the fly every time.
Sources: https://reactnative.dev/docs/stylesheet

Related

Would this approach to styling can cause performance problems?

If I create style sheet for all my components like this (so 1 component = 1 stylesheet file) would this approach to writing it make some performance issue?
My goal is to have access to theme properties but if this approach can make performance issue in the future I need to consider another approach.
import { StyleSheet } from "react-native";
import { useTheme } from '#react-navigation/native'
const dashboardStyles = (props) => StyleSheet.create({
progress: {
backgroundColor: props.colors.background,
},
});
function useStyles() {
const { colors } = useTheme();
const styles = React.useMemo(() => dashboardStyles({ colors }));
return styles;
}
export default useGlobalStyles;
Performance issues may come in several shapes and flavors depends on your current situation. In our case I think performance issues could be in the following categories:
Size - a large compressed application file may result in higher loads in terms of bandwidth for both client (waiting longer for app to start) and server (more resources required which usually means a higher cost)
UX - we want to deliver the best user experience possible meaning actions perform by user will be processes as fast as possible
Let's start with the easy on - UX. Since the react styling commands are injected to the browser's DOM as styling properties the performance gap between this process comparing to simply use fixed css files should be insignificant. So at least here we are certain that the user experience will not be affected.
When we are talking about size (which has an immediate effect on bandwidth) - we aim to make our app bundle as lightweight as possible. Our endgame is a working application that will also be as lightweight as possible.
From my experience with react you can reduce the size of styling follow these steps:
For each component create 1 css file containing the fixed styling (from some odd reason many developers use react to apply static styles) and set only the dynamic styles in your react file (very similar to the code you've already posted in your question)
When several components use the same basic style (or when you feel you are copy-and-paste styles across components) - create higher-level stylesheet files that will be re-used. This will help you to write less and use more and therefore - reduce the total size of your app bundle file
These should keep you app as lightweight as possible meaning less bandwidth and less memory consumed by your end-clients browsers (less memory allocations and more references to shared styles).
Technical note: please use general styling commands in your css files and more specific commands in your code (e.g. background or border when using fixed style and backgroundColor or borderWidth when using synamic style in your code). This will help you to better ensure that your dynamic style will always overwrite the fixed default (if there is any) in your fixed styling. More information and useful operators on this topic can be found here
I would structure my files as such:
theme.js
contains only styles, definitions of color palette, font types, and
sizes, widths and heights, things that'll be used globally, I use react-native-paper theme on this page.
commonPageStyles.js
contains only styles that are repeated in multiples pages, such as
page header, page description, anything..
ComponentX.js
the component that is reused with their style on the same page, e.g
a submit button
MyUniquePage.js
the style that is unique to this page
Very important note: a lot of the styles I declare end up being unused, and I lose track of them, and the style files'd only get bigger and uglier. so what I ended up doing. Is if the styles file doesn't need to live on an independant .js page, I'd include it in the component page and then use this VS code plugin "remove unused styles by xixi" to clean the unused styles page.
Don't Repeat Yourself(DRY) is best for boost your performance.. Yes, your approach of creating a globalStyles files and import that file and using it in your project is a good concept..
I would only suggest that while using your globalStyles don't
import allGlobalStyles from '../GlobalStyles';
Instead use
import {progress, errorStyle, pannelStyle} from '.../GlobalStyles';
which will only import a section of code to your component rather than importing entire file...
This is also useful while importing from npm packages too...
Like
import {isEmpty, isObject} from 'loadsh';

why React native doesn't push an option that allow developers customize default font? Is Overwriting render function a good choice?

1, I'm wondering why React native doesn't push an option that allow developers customize default font if it's a popular resonable need?
I've searched a number of posts and see some proposal solutions like: declares fontFamily every time we use Texts, declares common style and reuse, creates custom Text component to replace Text component from 'react-native', use theme provider and Text component from 'react-native-elements'... It says that a number of people needs this, but Text from 'react-native' hasn't supported this yet?
2, I search out a solution that overwrites render function of Text component (ex: https://github.com/Ajackster/react-native-global-props/blob/master/src/CustomFunctions/setCustomText.js) and consider where it's a good choice for this? is there any performance concern for it?

Should I use useMemo with React Native Webview?

Let's say I have a WebView and it's loading a fixed HTML string like:
const html = "<html>....</html>"
<AutoHeightWebView source={{html:html}} />
Would that be necessary to wrap it inside useMemo so the component doesn't get re-rendered more than necessary?
That depends on if html changes at all. If it doesn't, you may as well create a constants file outside the component and utilize it from there.
useMemo memoizes values dependant on certain state/dependency changes (React Documentation). Therefore if html does not change based on some other state/dependency changes, I don't think its necessary to wrap it in a useMemo.
However, you won't see any performance degradation/negative side-effects if you did wrap html in a useMemo.

How to update vue2-frappe chart?

I've been breaking my head over this for the last few hours and no matter where I look I can't seem to find the answer.
I'm using vue2-frappe as my chart library. I'm using a simple bar chart to display certain values by day. Everything was fine until my higher-ups decided they wanted to show a whole year's worth of values on this chart, meaning I have to add some pagination to it.
The problem is, now I can't figure out how to make the chart rerender. I've tried replacing the entire object I've bound the chart to, as well as manipulating specific values, but nothing seems to make the component rerender.
In the documentation for frappe.js, you can modify data via specific methods, but this being Vue I can't just call chart.update() like in normal .js. And if I inspect the component via vue dev tools, I can see it contains the modified data, it just doesn't redraw itself.
Anyone have an idea what to do?
I would try to force update the view component.
VueJs reactivity can sometimes be confusing where you think it should react to changes but it doesn't.
You can force a view update like so:
// Globally
import Vue from 'vue';
Vue.forceUpdate();
// Using the component instance
export default {
methods: {
methodThatForcesUpdate() {
// ...
this.$forceUpdate(); // Notice we have to use a $ here
// ...
}
}
}
You can read about correct ways of re-rendering here: https://michaelnthiessen.com/force-re-render
There are caveats to this approach as outlined in vueJs's docs: https://v2.vuejs.org/v2/guide/list.html#Caveats
Note #
A force re-render wont update computed values, but your computed property shouldn't contain any external non-reactive variable anyway.
Note 2
The above article written by Michael Thiessen also states the best way in his opinion is key-changing which I think we all should be aware of.
I hope this puts you on the right track. It sounds like (with limited information) you could be replacing the data but using the same key.

React Native with redux: what is a good way to store-manage dynamic styles?

I am creating an app with some style differences in portrait-landscape rendering.
For example the navigation bar height can be different and there are several sizes that I want to keep under strict control to make sure certain control/text fit to screen without scrolling.
I am fine with calculating stylesheets dynamically or caching them with either own utilities or utilities like react-native-extended-stylesheet yet.. where to store the calculated sheets for portrait landscape?
Possible options
1. A module level variable in my style.js. Possibly calculated on demand and cached later. I'd need to pass screen size to it though
2. Make styles a part of a state and update it on orientation changes action
3. Anything else
What makes most sense? What do you use in your applications?
I think a stylesheet library should take care about caching styles for landscape/portrait layouts and developer should just write styles and component logic.
I'm working on it currently here: https://github.com/vitalets/react-native-extended-stylesheet/issues/9
Until it is ready I think the best option is to cache on module level.
const styleLandscape = ...
const stylePorttrait = ...
Putting styles into component state will mix it with logic data that seems not good.