Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 66a8b94

Browse files
authored
chapter 9 and 9.1 with redux integration (#10)
1 parent c4ab15b commit 66a8b94

File tree

4 files changed

+234
-3
lines changed

4 files changed

+234
-3
lines changed

‎book/9-redux/9.0-intro.md

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Redux - The State Container
2+
3+
We assume that the reader is already aware of Redux. But just to refresh, according to redux.js.org:
4+
5+
> Redux is a predictable state container for JavaScript apps. It helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test. On top of that, it provides a great developer experience, such as live code editing combined with a time traveling debugger.
6+
7+
In a nutshell, redux is a state container. That is it will contain all our runtime application state or data.
8+
9+
Redux essentially has a three parts:
10+
- Store - Store contains a global state for the entire app. It is basically the manager for the application state.
11+
- Actions - These are like the commands you pass to store along with some data to do some modifications to the stored state.
12+
- Reducers - Reducers are basically functions that the store calls whenever a action arrives. The reducers are the ones which determines what the new state will be based on the actions and the action payload it receives.
13+
14+
### But we already have React's state
15+
16+
Both Redux and React's state are used to manage the state in the application. But, both Redux and React's state are very different in the way they work and it is good to know when to use what.
17+
18+
React state is stored locally within a component. When it needs to be shared with other components, it is passed down through the props. Hence, this means all the components which need the state data need to be the child of the component holding the value.
19+
But in case of Redux, state is stored globally in the Redux store. Components subscribe to the store to get access to the value. This centralizes all data but makes it very easy for a component to get the state it needs, without surrounding components knowing of its needs.
20+
21+
So, this means that Redux is good and we should just use it for all our app state management.
22+
23+
**NO !**
24+
25+
While redux is helpful in some cases, it will create unnecessary indirections for simpler and trivial use cases.
26+
Consider that we have a text input. And since we are using redux, we decide to use redux to store all the changes in the text field in redux. In redux for changing the state on text input, we will need to create an Action, write a reducer and then subscribe our component to the store so that it re renders on every state change. This is bad! Why so much complication?
27+
28+
*Dan Abramov* - The creator of redux says you might actually not need redux unless you have a plan to benefit from this additional indirection. In his blog at https://medium.com/@dan_abramov/you-might-not-need-redux-be46360cf367, he clearly states that since redux introduces an additional indirection to managing the state of the application, we should use it only if it benefits us.
29+
30+
Now, lets see when we should use redux and when React's state is good enough.
31+
32+
One way to do this is based on Duration of the data we want to store.
33+
As, *Tyler Hoffman* explains in his blog post https://spin.atomicobject.com/2017/06/07/react-state-vs-redux-state/,
34+
35+
Different pieces of state are persisted for different amounts of time. We can categorize data into:
36+
37+
- **Short term**: data that will change rapidly in your app
38+
- **Medium term**: data that will likely persist for a while in your app
39+
- **Long term**: data that should last between multiple app launch.
40+
41+
#### Short term data
42+
Short term data is something that changes very quickly and is needed to be stored only for small amount of time. For example, this includes the characters that the user types in a text field. This data is not needed once the user submits the form.
43+
Also we will not need to mostly transfer this type of data to any other independent component. Such type of data clearly fits the use case for React's state.
44+
45+
46+
#### Medium term data
47+
Medium term data needs to stick around while the user navigates the app. This could be data loaded from an API, or any changes that needs to be persisted up until a page refresh. This can also contain data that needs to be used by a component that is completely unrelated to the component that produced the data. As an example, consider that one of the component makes an API call on a button click to update user's profile details. The data returned from the server needs to be stored and will be used by a completely unrelated profile screen. Now, if the data is was stored in some global location. It would be far easier to access this data. Such type of use cases clearly fits Redux.
48+
49+
#### Long term data
50+
This is the data that should be persisted between refreshes of the page or when the user closes and reopens the app. Since the Redux store is created on app launch, this type of data should be stored somewhere else, for example: Async Storage in the case of React Native.

‎book/9-redux/9.1-redux-setup.md

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# Setting up Redux for React Native
2+
3+
Let begin by installing few packages.
4+
5+
`yarn add redux react-redux redux-promise redux-thunk`
6+
7+
or
8+
9+
`npm install --save redux react-redux redux-promise redux-thunk`
10+
11+
- **redux** - the main redux library.
12+
- **react-redux** - the react bindings for redux, which makes our life easy when using redux with react.
13+
- **redux-promise** - promise middleware for Redux.
14+
- **redux-thunk** - Thunk middleware for redux (explained in detail in later chapter).
15+
16+
17+
Now create the files
18+
**`app/redux/store.js`**
19+
```js
20+
21+
import {createStore, compose, applyMiddleware} from 'redux';
22+
import thunk from 'redux-thunk';
23+
import promise from 'redux-promise';
24+
import rootReducer from './reducers/root.reducer';
25+
26+
const enhancerList = [];
27+
const devToolsExtension = window && window.devToolsExtension;
28+
29+
if (typeof devToolsExtension === 'function') {
30+
enhancerList.push(devToolsExtension());
31+
}
32+
33+
const composedEnhancer = compose(applyMiddleware(thunk, promise), ...enhancerList);
34+
35+
const initStore = () => createStore(rootReducer, {}, composedEnhancer);
36+
37+
module.exports = {
38+
initStore
39+
};
40+
41+
```
42+
**`app/redux/reducers/root.reducer.js`**
43+
```js
44+
import {combineReducers} from 'redux';
45+
46+
export default combineReducers({
47+
48+
});
49+
```
50+
51+
Now lets initialize the store.
52+
53+
Modify the file:
54+
**`app/index.js`**
55+
```js
56+
import React, {Component} from 'react';
57+
import {initStore} from './redux/store';
58+
import {Provider} from 'react-redux';
59+
60+
import App from './App.container';
61+
62+
const store = initStore();
63+
64+
class NoteTaker extends Component {
65+
render () {
66+
return (
67+
<Provider store={store}>
68+
<App />
69+
</Provider>
70+
);
71+
}
72+
}
73+
74+
export default NoteTaker;
75+
```
76+
77+
and move the Initialization of the home component to another file
78+
79+
**`app/App.container.js`**
80+
```js
81+
import React, {Component} from 'react';
82+
import Home from './components/Home/Home.component';
83+
import {connect} from 'react-redux';
84+
85+
class App extends Component {
86+
render () {
87+
return (
88+
<Home />
89+
);
90+
}
91+
}
92+
93+
const mapStateToProps = (state) => ({
94+
state
95+
});
96+
97+
const mapDispatchToProps = (dispatch) => ({
98+
dispatch
99+
});
100+
101+
export default connect(mapStateToProps, mapDispatchToProps)(App);
102+
```
103+
104+
105+
Now, lets add our first reducer and action.
106+
107+
108+
Create the files:
109+
**`app/redux/actions/index.actions.js`**
110+
This file will contain all our actions.
111+
112+
```js
113+
export const TEST_ACTION = 'TEST_ACTION';
114+
```
115+
116+
**`app/redux/reducers/test.reducer.js`**
117+
```js
118+
import {TEST_ACTION} from '../actions/index.actions';
119+
120+
const test = (state = {}, action) => {
121+
switch (action.type) {
122+
case TEST_ACTION: {
123+
return action.payload;
124+
}
125+
default:
126+
return state;
127+
}
128+
};
129+
130+
export default test;
131+
```
132+
Now lets add our test reducer to the root reducer.
133+
134+
Modify **`app/redux/reducers/root.reducer.js`**
135+
136+
```js
137+
import {combineReducers} from 'redux';
138+
import test from './test.reducer';
139+
140+
export default combineReducers({
141+
test
142+
});
143+
```
144+
145+
At this point, we should a have a redux store with an initial test state from the test reducer.
146+
147+
To check this, lets run our app on the simulator.
148+
149+
Launch the react-native-debugger.
150+
151+
Now open up the debug menu on the iOS simulator by pressing `cmd+ctrl+z` or on Android emulator by using `cmd+m`.
152+
153+
Choose `Debug JS Remotely`.
154+
155+
This should run the app js code in react-native-debugger and if all went well we should see something like this on the redux panel:
156+
157+
<br>
158+
<div style="text-align:center">
159+
<img src="/assets/images/9/9.1/9.1-redux-setup.png" style="width: 80%;display:inline-block;" hspace="20">
160+
</div>
161+
<br>
162+
163+
This implies that our redux store successfully initialized with the test reducer.
164+
165+
166+
NOTE:
167+
168+
If your tests fail due to the error:
169+
170+
`window not defined`
171+
172+
then add a mock file
173+
**`__mocks__/react-native.js`**
174+
175+
```js
176+
var rn = require('react-native');
177+
global.window = global;
178+
module.exports = rn;
179+
```
180+
181+
This will initialize a dummy window variable when tests are run in node environment.

‎book/SUMMARY.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@
1212
* [Github Pre-push/Pre-commit Hooks](6-conventions-and-code-style/6.2-git-pre-hooks.md)
1313
* [Environment Variables](6-conventions-and-code-style/6.3-environment-variables.md)
1414
* [Speed up development with some and ES7 features 🤘](6-conventions-and-code-style/6.4-es7-features.md)
15-
* [Testing](7-testing/7.0-intro.md)
15+
* [Testing and Debugging](7-testing/7.0-intro.md)
1616
* [Jest setup](7-testing/7.1-jest-setup.md)
1717
* [Snapshots](7-testing/7.2-snapshots.md)
1818
* [Testing stateful components using Enzyme](7-testing/7.3-enzyme-testing.md)
1919
* [Mocking RN modules ](7-testing/7.4-mocking-rn-modules.md)
2020
* [FYI Cache](7-testing/7.5-fyi-cache.md)
21+
* [Using React-Native Debugger for debugging]((7-testing/7.6-using-react-native-debugger-for-debugging.md)
2122
* [Styling 💅🏻](8-styling/8.0-intro.md)
2223
* [Theme Variables](8-styling/8.1-theme-variables.md)
2324
* [Common Styles/Mixins](8-styling/8.2-common-styles-mixins.md)
@@ -33,8 +34,7 @@
3334
* [Integrating with redux store](10-navigation/10.2-integrating-with-redux-store.md)
3435
* [File Structure for routes](10-navigation/10.3-file-structure-for-routes.md)
3536
* [Styling headers](10-navigation/10.4-styling-headers.md)
36-
* [Debugging and DevOps](11-debugging-devops/11.0-debugging-devops.md)
37-
* [Using React-Native Debugger for debugging](11-setting-up-the-project/11.2-using-react-native-debugger-for-debugging.md)
37+
* [DevOps](11-debugging-devops/11.0-debugging-devops.md)
3838
* [Travis CI setup](11-setting-up-the-project/11.3-travis-ci-setup.md)
3939
* [Test Fairy setup](11-setting-up-the-project/11.4-test-fairy-setup.md)
4040
* [Github Releases](11-setting-up-the-project/11.5-github-releases.md)
244 KB
Loading[フレーム]

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /