As described on their website, React Native is a framework for building native apps using React. React itself, is a Javascript library for building user interfaces. The 3 capital notions in React Native are: components, states and props.
Components are UI elements that manage their own states and props. In a React Native application, one or more components are used to compose a view.
Each component can be customized with props and state. Keep in mind that the render of a component is fully linked to props and state. It will be always the same render, with same props and states.
Also, each time of a state or a props changes, the render methods of the component and children components are called. To keep good performances, you can use the shouldComponentUpdate(nextProps, nextState)
method to let let React know if a component’s output is not affected by the current change in state or props.
Other methods are important to know for component lifecycle management:
These methods are called when an instance of a component is being created and inserted into the DOM:
An update can be caused by changes to props or state. These methods are called when a component is being re-rendered:
This method is called when a component is being removed from the DOM:
Props are parameters that are set by their parents when components are created. These props can then be used in the component render method.
// in the component file
class Hello extends Component {
render() {
return (
<Text>Hello {this.props.name}!</Text>
);
}
}
// to use the component
<View>
...
<Greeting name='Rexxar' />
...
</View>
```
# State
While props are fixed throughout the lifetime of a component, the state is used for data that is going to change.
The component is updated when the `setState()` method is called.
### Initialise the state
````javascript
class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {isShowingText: true}; //state init
setInterval(() => {
this.setState(previousState => {
return { isShowingText: !previousState.isShowingText };
});
}, 1000);
}
render() {
let display = this.state.isShowingText ? this.props.text : ' ';
return (
<Text>{display}</Text>
);
}
}
```
# Styling
React Native use stylesheets, that reminds CSS syntax.
### Exemple
````javascript
render() {
return (
<Text style={styles.bigblue}>Hello</Text>
)
}
const styles = StyleSheet.create({
bigblue: {
color: 'blue',
fontWeight: 'bold',
fontSize: 30,
},
red: {
color: 'red',
},
});
```
# Networking
React Native provides the Fetch API for your networking needs. You can additionnaly use Javascript "Promise" to handle the whole Networking exchange
### Exemple
````javascript
export const searchService = pattern => new Promise((res, rej)=>{
fetch(`${API_URL}?term=${pattern}`)
.then(
resp => resp.json()
)
.then(
apiData=>res(apiData)
)
.catch(
err=>rej(err)
)
})
```
### Usage
````javascript
myComponentFunction() {
searchService(pattern)
.then(
apiData => this.setState({res: [...apiData.results]})
).catch(
err => console.log(err)
)
}
For projects with redux
.
├── _tests // test folder
├── android // Android related folder
├── app // main application folder
│ ├── actions // all the actions used by redux
│ ├── components // all the React Native components
│ ├── constants // all const files
│ ├── middleware // middleware for all actions
│ ├── reducers // redux stuff
│ ├── scenes // all scenes of the app
│ └── services // all the networking stuff
│ └── utils // utils code shared in the app
├── assets
│ ├── fonts
│ └── images
└── ios // iOS related folder
Used to create a queue of actions, for non-blocking treatment and order respect.
export default (store) => (next) => (action) => {
let syncActivityFinished = false;
let actionQueue = [];
function flushQueue() {
actionQueue.forEach(a => store.dispatch(a));
actionQueue = [];
}
function asyncDispatch(asyncAction) {
actionQueue = actionQueue.concat([asyncAction]);
if (syncActivityFinished) {
flushQueue();
}
}
const actionWithAsyncDispatch = Object.assign({}, action, {asyncDispatch});
next(actionWithAsyncDispatch);
syncActivityFinished = true;
flushQueue();
};
All the actions are then linked with
const store = createStore(AppReducers, applyMiddleware(AsyncDispatchMiddleware));
import {Platform, StyleSheet} from 'react-native';
const styles = StyleSheet.create({
containerA: {
height: Platform.OS === 'ios' ? 200 : 100
},
container: {
flex: 1,
...Platform.select({
ios: {
backgroundColor: 'red',
},
android: {
backgroundColor: 'blue',
},
}),
},
});
import {Platform} from 'react-native';
if (Platform.Version === 25) {
console.log('Running on Nougat!');
}
import {Platform} from 'react-native';
const majorVersionIOS = parseInt(Platform.Version, 10);
if (majorVersionIOS <= 9) {
console.log('Work around a change in behavior');
}
Create 2 differents files
BigButton.ios.js
BigButton.android.js
At import, it will automatically select the good version
const BigButton = require('./BigButton');