Skip to content

Instantly share code, notes, and snippets.

@inspireui
Last active June 29, 2018 11:08
Show Gist options
  • Save inspireui/98784098cdc9039b20d31cc885c5fac1 to your computer and use it in GitHub Desktop.
Save inspireui/98784098cdc9039b20d31cc885c5fac1 to your computer and use it in GitHub Desktop.
React Native performance
Author: inspireUI
Website: inspireui.com
- Should be use PureComponent to avoid re-render many times --> https://reactjs.org/docs/react-api.html#reactpurecomponent
- Seperate Container file and Component file --> https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0
- Avoid use .bind when handle function --> https://stackoverflow.com/a/32192892/6622971
- Don’t use arrow functions in your render methods --> onPress={(e) => this.handlePress(e)} --> only use when need pass params to handle, or
export default ({deleteItem, item}) => {
const _onDeleteTap(){
deleteItem(item.id)
}
return(
<TouchableOpacity onPress={_onDeleteTap}>
<Text>Delete</Text>
</TouchableOpacity>
) }
- Use Redux carefully which avoid re-render many times and avoid use unnecessary. Can use reselect https://github.com/reduxjs/reselect.
- Should be use .eslint to clean code and warning unuse.
- Should be handle "loading" when fetch api do not finish.
- prettier --write App/**/*.js
/**
- Don’t use arrow functions in your render methods.
- Should break them out into their own functions and/or components when needed.
- And If using eslint which will show warning about Pure Component
*/
export default ({deleteItem, item}) => {
const _onDeleteTap(){
deleteItem(item.id)
}
return(
<TouchableOpacity onPress={_onDeleteTap}>
<Text>Delete</Text>
</TouchableOpacity>
) }
renderItem(item){
return (
<View>
<Text>{item.title}</Text>
<DeleteMe deleteItem={this.deleteItem} item={item} />
</View>
)}
render(){
const {items} = this.props;
return (
<View>
{items.map(this.renderItem)}
</View>
) }
/**
- Avoid use .bind when handle function
- Ref: https://stackoverflow.com/a/32192892/6622971
*/
class Foo extends React.Component {
handleBar = () => {
console.log('neat');
};
handleFoo = () => {
console.log('cool');
};
render() {
return (
<div
onClick={this.handleBar}
onMouseOver={this.handleFoo}
/>
);
}
}
/**
- Try to use cache stylestheet instead of inline, to take adavantage from RN cache
- Overwriting styles by using array of style object
*/
const styles = StyleSheet.create({
label: {
fontSize: 20,
}
});
class UserComponent extends Component {
render(){
return(
<Text styles={styles.label}>Hello</Text>
)
} }
/**
* Show loading to avoid render unnecessary and improve UX
*/
/**
* Show loading to avoid render unnecessary and improve UX
*/
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import { View, Text } from 'react-native'
import { Loading } from '@components'
export default class Home extends Component {
static propTypes = {
data: PropTypes.object,
isLoading: PropTypes.bool.isLoading
}
static defaultProps = {
isLoading: false
}
render() {
if (this.props.isLoading || !this.props.data) return <Loading />
return (
<View>
<Text>{this.props.data.name}</Text>
</View>
)
}
}
/**
- Should be use PureComponent to avoid re-render many times
- Ref: https://reactjs.org/docs/react-api.html#reactpurecomponent
*/
import React, { PureComponent } from 'react'
import PropTypes from 'prop-types'
import { View, Text, TouchableWithoutFeedback, Image } from 'react-native'
import { Languages, Tools } from '@common'
import styles from './styles'
export default class UserProfileHeader extends PureComponent {
// constructor(props) {
// super(props)
// }
static propTypes = {
onLogin: PropTypes.func.isRequired,
onLogout: PropTypes.func.isRequired,
user: PropTypes.object,
}
loginHandle = () => {
if (this.props.user.name === Languages.Guest) {
this.props.onLogin()
} else {
this.props.onLogout()
}
}
render() {
const { user } = this.props
const avatar = Tools.getAvatar(user)
return (
<View style={styles.container}>
<View style={styles.header}>
<Image source={avatar} style={styles.avatar} />
<View style={styles.textContainer}>
<Text style={styles.fullName}>{user.name}</Text>
<Text style={styles.address}>{user ? user.address : ''}</Text>
<TouchableWithoutFeedback onPress={this.loginHandle}>
<Text style={styles.loginText}>
{user.name === Languages.Guest
? Languages.Login
: Languages.Logout}
</Text>
</TouchableWithoutFeedback>
</View>
</View>
</View>
)
}
}
/**
- Use Selectors to access State
- Note use filter at connect function as it will see this filter as a new object every time it does its comparison
- When linking your Redux state to your component via a Connect (React Redux). Try to only include the pieces of state you abso- lutely need for that view. Accessing extra data will cause that component to update when those pieces of data change.
*/
// CarSelector.js
import { createSelector } from 'reselect';
const allCars = (state) => state.Cars;
const searchingColor = (state, props) => props.color;
export const carSelector = createSelector([allCars, searchingColor], (cars, color) => {
return cars.filter((car) => car.color === color);
});
// BlueCarsView.js
import {carSelector} from 'CarSelector.js';
export default connect(
(state, ownProps) => ({
cars: carSelector(state, ownProps)
}), false
)(BlueCarsView)
<BlueCarsView color={'blue'} />
/**
* Stateless component to improve performance
* Shoule be add propTypes to check validate props
*/
import React from 'react'
import PropTypes from 'prop-types'
// import { Image } from 'react-native'
import FastImage from 'react-native-fast-image'
const ImageCache = ({ style, uri }) => {
return (
<FastImage
style={style}
source={{ uri, priority: FastImage.priority.normal }}
// resizeMode={FastImage.resizeMode.contain}
/>
)
}
ImageCache.propTypes = {
style: PropTypes.any,
uri: PropTypes.any,
}
export default ImageCache
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment