preface
If you want to see the theory of children click here redux Chinese document or redux official document, this article will not deliberately introduce a large length of theory, this article does not make a comparison between the framework, only for children who want to learn Redux to provide substantive, efficient, easy to understand the learning reference resources, share their own learning process. The article will be longer after the update, please be patient to read and understand, carefully taste. It doesn’t matter if you are not familiar with Redux, you can follow the article ideas and finish the three demos. I believe you will benefit a lot. (The egg is painted after the article.)
Updated content
redux
Basic use (with demo)redux
Middleware
Use (with demo)redux
integrationnavigation
(demo)
Todos
react native
async
react native
Integrate the first two DOMOs with react-native navigation.
Content to Be Updated
- To be continued…
Why am I writing this demo
Some children may have doubts
Q: Isn’t the official Todosdemo? Why did I write this demo?
A: Official Demos are react, not React Native. I also looked for a lot of articles about Redux, but I found that the materials I found were too basic or not comprehensive, the demo download didn’t work, etc., and I was motivated to build my own wheel, and this demo wasn’t just about the basics of Redux. But through three sets of demo practice coherent graphics, let readers better understand, later will be updated in the process of using Redux, hope you encourage support.
Code specification used by Demo
A large project usually involves many developers at the end of the project, and if each developer uses his or her own set of code specifications, the result will be: Late code management is a hassle, takes more time to refactor, takes more time for new people to understand the code, and drives people away, so a large project has to follow some specifications when it’s first architecting.
So how can we type clean and elegant code? How do we check the quality of our code? I highly recommend following the Airbnb /javascript spec and using ESLint to check the quality of your code as they have been approved by many companies and developers. (There is too much introduction to Airbnb ESLint, this article only provides ideas, want to know more search by yourself)
Without using code specification before we could use their own style to write the code for many years, suddenly want to adapt to this specification may be very not adapt, it doesn’t matter, more practice more, time grew to become accustomed to, who is not a process, the process is bitter, but the pain after brings qualitative sublimation, slowly understand understand yourself. Good things will be accepted by the world, and bad things will eventually be replaced, so as a qualified programmer (especially front-end programmers) embrace change, because it will make you better and get accepted by the public, unless you don’t want to make yourself better.
What can Redux do for us
Two pictures:
Story features
-
Single data source: for the entire applicationstateIs stored in an object tree and exists in only one object treestoreIn the.
-
State is read-only: the only way to change State is to triggeractionAction is a generic object that describes events that have occurred.
-
Use pure functions to perform modifications: To describe how an action changes the state tree, you need to writereducers.
-
Predictability: All user behavior is defined in advance by you.
-
Unified management state: All states are allocated and managed in a store.
Which developers and projects are suitable for Redux
For react Native development only:
-
I don’t recommend using React Native because you don’t know how to use it. It is recommended to reach intermediate level first.
-
Intermediate: Use React Native to create one or more uncomplicated redux applications that are already on the market, or don’t use them, because using redux doesn’t allow you to develop quickly and iteratively up front. Using Redux on projects like this is like shooting a cannon at a mosquito with a lot of side effects. But you can understand it first and find its advantages. This is a relatively simple application: when the user triggers an action (the application needs setState({XXX: XXX})), the application state flow looks like this:
-
Advanced: Use React Native to create a complex application that is already on the shelves (involving im, complex interface layout, too many layers of nested components, etc.). When the user triggers an action (setState({XXX: XXX})), the application state flow looks like this:
The consequences of this state are analyzed from two aspects:
- Performance: Redundant state passing between subcomponents leads to a waste of valuable memory resources, while the interface renders slowly, resulting in a poor user experience.
- State management: As the program iterates and the interface layout becomes more and more complex, it is inevitable that many
state
States, how do you manage those states effectively? What causes the UI to render multiple times? Which action caused the change in the UI component? In no useredux
Previously you may have found that you can use the life cycle functionshouldComponentUpdate
To reduce unnecessary rendering in child components, but ultimately does not solve the complex problem of state management. When you useredux
After that, the complex application state flow looks like this:
After reading the above pictures and pictures, do you have an intuitive understanding of what kind of project is suitable for redux? Thank you@justjavacGIF support provided by the article.
Redux for React Native working logic diagram
Thanks to @Blackforest Studio author for the clear logic diagram
Redux engineering structure analysis
I made some changes to the official demo in a small part of the location to see the code analysis:
The division of subsidiary
js/actions
What this folder does is define user behavior.js/reducers
What this folder does is respond to the user’s behavior, return the changed state, and send itstore
.js/components
Here’s what this folder does: custom components.js/containers
This folder drops content to do the followingcomponents
Components in the folder that are involved in state changes are encapsulated a second time.App.js
The entry file (Store is here), why do I define store here? Because it is unique and must be usedreact-redux
To provide theProvider
Component package entry for other componentsredux
In thestore
To take effect.global.js
Store globally defined variables, constants, methods, etc.
Something to watch out for
- In a project
redux
的store
Be unique and cannot be in multiplestore
。 - keep
reducer
Purity is very important. Never in the worldreducer
To do these operations:
- Modify the passed parameter;
- Perform operations that have side effects, such as
API
Request and route hops;- Call an impure function, such as
Date.now()
或Math.random()
;
- Use the object expansion operator
.
Instead ofObject.assign()
Is the best solution. - The component name must be capitalized, i.e
components
andcontainers
All files in folders should begin with a capital letter. - You should minimize pass-through to
action
Data in (can transmit a data do not pass object, can transmit an object do not pass array)
//good
function todoApp(state = initialState, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER:
return Object.assign({}, state, {
visibilityFilter: action.filter
})
default:
return state
}
}
Copy the code
//best
function todoApp(state = initialState, action) {
switch (action.type) {
case SET_VISIBILITY_FILTER:
return { ...state, visibilityFilter: action.filter }
default:
return state
}
}
Copy the code
Code,
js/actions/types.js
// Add list dataexport const ADD_TODO = 'ADD_TODO'; / / filterexport const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER'; // Add/ununderline textexport const TOGGLE_TODO = 'TOGGLE_TODO';
Copy the code
Shih:
The action definition
Why should I separate out the user’s action definition and write type.js?
- Convenient state management.
- Reusability.
js/actions/index.js
import {
ADD_TODO,
SET_VISIBILITY_FILTER,
TOGGLE_TODO,
} from './types'
let nextTodoId = 0;
export const addTodo = text => ({
type: ADD_TODO,
id: nextTodoId++,
text
});
export const setVisibilityFilter = (filter) => ({
type: SET_VISIBILITY_FILTER,
filter
});
export const toggleTodo = id => ({
type: TOGGLE_TODO,
id
});
Copy the code
Shih:
Action create function
The Action creation function is the method that generates the Action. The concepts of “action” and “action creates a function” are easily confused and are best distinguished when used.
The action creation function in Redux simply returns an action:
js/reducers/todos.js
import {
ADD_TODO,
TOGGLE_TODO,
} from '.. /actions/types'
const todos = (state = [], action) => {
let {id, text, type} = action;
switch (type) {
case ADD_TODO:
return [
...state,
{
id: id,
text: text,
completed: false}];case TOGGLE_TODO:
returnstate.map(todo => (todo.id === id) ? {... todo, completed: ! todo.completed} : todo); default:returnstate; }};export default todos;
Copy the code
js/reducers/visibilityFilter.js
import { SET_VISIBILITY_FILTER } from '.. /actions/types'
import { visibilityFilters } from '.. /global'
const { SHOW_ALL } = visibilityFilters;
const visibilityFilter = (state = SHOW_ALL, action) => {
let {type, filter} = action;
switch (type) {case SET_VISIBILITY_FILTER:
return filter;
default:
return state
}
};
export default visibilityFilter;
Copy the code
Shih:
reducer
It’s a pure function that accepts the oldstate
和 action
, return newstate
The above two files can look at tworeducer
).
Note:
Redux
The first time I do it,state
为undefined
In this case, you need to set to return to the initial applicationstate
.- each
reducer
Just managing the big picturestate
For which it is responsible. eachreducer
的state
The parameters are different, corresponding to the part it managesstate
The data.
js/reducers/index.js
import { combineReducers } from 'redux'
import todos from './todos'
import visibilityFilter from './visibilityFilter'
export default combineReducers({
todos,
visibilityFilter
})
Copy the code
Shih:
combineReducers()
All you do is generate a function that calls your seriesreducer
, eachreducer
Filter them out by their keystate
Part of the data and processingAnd then the generated function takes all of thereducer
Merges the result into one large object.
The seemingly combineReducers() function is to combine multiple reducers into a reducer.
js/components/Todo.js
import React, { Component } from 'react'
import {
Text,
TouchableOpacity
} from 'react-native'
import PropTypes from 'prop-types'
export default class Todo extends Component {
static propTypes = {
onClick: PropTypes.func.isRequired,
completed: PropTypes.bool.isRequired,
text: PropTypes.string.isRequired
};
render() {let { onClick, completed, text } = this.props;
return (
<TouchableOpacity
style={{
flexDirection: 'row',
flex: 1,
height: 50,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#cccccc',
marginTop: 10
}}
onPress={onClick}>
<Text style={{ textDecorationLine: completed ? 'line-through' : 'none'}}>{text}</Text> </TouchableOpacity> ); }}Copy the code
js/components/TodoList.js
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import {
FlatList
} from 'react-native'
import Todo from './Todo'
export default class TodoList extends Component {
static propTypes = {
todos: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.number.isRequired,
completed: PropTypes.bool.isRequired,
text: PropTypes.string.isRequired
}).isRequired
).isRequired,
toggleTodo: PropTypes.func.isRequired
};
_renderItem = (data) => {
let dataItem = data.item;
let { id } = dataItem;
let { toggleTodo } = this.props;
return( <Todo {... dataItem} onClick={() => toggleTodo(id)} /> ) };render() {
let { todos } = this.props;
return (
<FlatList
data={todos}
keyExtractor={(item)=>item.id.toString()}
renderItem={this._renderItem}
/>
)
}
}
Copy the code
js/components/Link.js.js
import React, { Component } from 'react'
import PropTypes from 'prop-types'
import {
TouchableOpacity,
Text
} from 'react-native'
export default class Link extends Component {
static propTypes = {
active: PropTypes.bool.isRequired,
filter: PropTypes.string.isRequired,
onClick: PropTypes.func.isRequired
};
render() {
let { active, filter, onClick } = this.props;
return (
<TouchableOpacity
style={{
marginLeft: 4,
height: 40,
flex:1,
borderWidth: 1,
borderColor: '#ccc',
alignItems: 'center',
justifyContent:'center'
}}
onPress={onClick}
>
<Text style={{fontSize: 10, color: active ? 'black' : '#cccccc'}}>{filter}</Text> </TouchableOpacity> ); }}Copy the code
js/components/Filters.js
import React, { Component } from 'react'
import {
View,
} from 'react-native'
import FilterLink from '.. /containers/FilterLink'
import { visibilityFilters } from '.. /global'
const { SHOW_ALL, SHOW_COMPLETED, SHOW_ACTIVE } = visibilityFilters;
export default class Filters extends Component {
render() {return(
<View style={{ flexDirection: 'row', marginTop: 20}}>
<FilterLink filter={SHOW_ALL} />
<FilterLink filter={SHOW_COMPLETED} />
<FilterLink filter={SHOW_ACTIVE} />
</View>
)
}
}
Copy the code
Shih:
The above four files are four custom UI presentation components that define the look and feel regardless of where the data comes from and how it changes. Render what is passed in. If you take the code fromRedux
When you migrate to another architecture, these components can be used without any changes. They don’t depend onRedux
.
js/containers/AddTodo.js
import React, { Component } from 'react'
import {
View,
TextInput,
Button,
} from 'react-native'
import { connect } from 'react-redux'
import { addTodo } from '.. /actions'
class AddTodo extends Component {
constructor(props){
super(props);
this.inputValue = ' ';
}
render() {let { dispatch } = this.props;
return (
<View style={{flexDirection: 'row'}}>
<TextInput
style={{flex:1, borderWidth: 1, borderColor: '#cccccc', textAlign: 'center'}}
onChangeText={text => this.inputValue = text}
/>
<Button title="Add Todo" onPress={() => dispatch(addTodo(this.inputValue))}/>
</View>
)
}
}
export default connect()(AddTodo)
Copy the code
js/containers/FilterLink.js
import { connect } from 'react-redux'
import { setVisibilityFilter } from '.. /actions'
import Link from '.. /components/Link'
const mapStateToProps = (state, ownProps) => ({
active: ownProps.filter === state.visibilityFilter,
filterText: ownProps.filter
});
const mapDispatchToProps = (dispatch, ownProps) => ({
onClick: () => dispatch(setVisibilityFilter(ownProps.filter))
});
export default connect(
mapStateToProps,
mapDispatchToProps,
)(Link)
Copy the code
js/containers/VisibleTodoList.js
import { connect } from 'react-redux'
import { toggleTodo } from '.. /actions'
import TodoList from '.. /components/TodoList'
import { visibilityFilters } from '.. /global'
const { SHOW_ALL, SHOW_COMPLETED, SHOW_ACTIVE } = visibilityFilters;
const getVisibleTodos = (todos, filter) => {
switch (filter) {
case SHOW_COMPLETED:
return todos.filter(t => t.completed);
case SHOW_ACTIVE:
returntodos.filter(t => ! t.completed);case SHOW_ALL:
return todos;
default:
throw new Error('Unknown filter: ' + filter)
}
};
const mapStateToProps = state => ({
todos: getVisibleTodos(state.todos, state.visibilityFilter)
});
const mapDispatchToProps = dispatch => ({
toggleTodo: id => dispatch(toggleTodo(id))
});
export default connect(
mapStateToProps,
mapDispatchToProps,
)(TodoList)
Copy the code
Shih:
The above three are container components that connect the presentation component to Redux. Bottom line: Just remember one thing: the UI presentation component is responsible for rendering the UI, and the container component is responsible for managing the data and logic. Sometimes it’s hard to tell whether to use container components or presentation components. Such as this small component:
AddTodo.js
Contains an “Add” button and input box
It’s technically possible to split it into two components, but it’s a little early to start. It is possible to mix containers and presentations in very small components. As businesses get more complex, it becomes obvious how to break them up. So go for the hybrid now.
The react-Redux connect() method is used to associate presentation and container components together, which is optimized to avoid many unnecessary duplicate renderings. (This way you don’t have to manually implement the shouldComponentUpdate method in the React performance optimization suggestion for performance.)
Before using connect(), you need to define the function mapStateToProps to specify how to map the current Redux store state to the props of the presentation component. For example, VisibleTodoList needs to evaluate todos passed to TodoList, so a method to filter state.todos based on state.visibilityFilter is defined and used in mapStateToProps.
In addition to reading state, container components can also distribute actions. In a similar manner, the mapDispatchToProps() method can be defined to receive the Dispatch () method and return the callback method expected to be injected into the props of the presentation component. For example, we want VisibleTodoList to inject a props called onTodoClick into the TodoList component, and we want onTodoClick to distribute the TOGGLE_TODO action. Finally, create the VisibleTodoList using connect() and pass in both functions.
js/components/Group.js
import React, { Component } from 'react'
import {
View
} from 'react-native'
import AddTodo from '.. /containers/AddTodo'
import Filters from '.. /components/Filters'
import VisibleTodoList from '.. /containers/VisibleTodoList'
export default class Group extends Component {
render() {
return( <View style={{paddingHorizontal: 20, paddingVertical: 44}}> <AddTodo/> <Filters/> <VisibleTodoList/> </View> ); }}Copy the code
Shih:
Group.js
It is to string all the associated components together to form a complete interface.
App.js
import React, { Component } from 'react'
import { createStore } from 'redux'
import { Provider } from 'react-redux'
import Group from './js/components/Group'
import rootReducer from './js/reducers'
export default class App extends Component {
render() {
const store = createStore(rootReducer);
return( <Provider store={store}> <Group /> </Provider> ); }}Copy the code
Shih:
Import file incomingStore
- create
store
The incomingreducers
. - use
Provider
The component packageGroup
Components,store
Passed in as an attributeProvider
.
At this point, the code analysis is complete. This is the end of this writing. I believe that if you read carefully, more or less there will be some harvest, if the demo does not understand, then follow the idea of code analysis to type the code several times, also understand, I will continue to update the unfinished content.
~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️
⭐️⭐ ⭐ ⭐ ⭐️⭐ ⭐ ⭐️⭐️ disk disk disk disk disk disk disk disk disk disk disk disk disk
~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️
It’s been a couple of days since the last update, but today’s update is about Middleware.
The role of Middleware
Middleware is a tool that is embedded between Actions and Dispatcher to solve problems and improve our development efficiency. There are three common types of middleware:
- Redux-thunk middleware: Asynchronous operations are needed in a project (e.g., requests for server data, local storage, etc.).
- redux-actionsMiddleware: Helps process and create operations
actions
(This is not covered in this article, but you can use it to create future projects when they are more complex). - redux-loggerMiddleware: Used for printing
action
The logs. openreact native
Remote debug mode, operation demo can see the printed status changes in the console.
After the middleware is added, the schematic diagram is as follows:
Core code details
In order to reduce the length of the article, this demo code will only explain the parts involved in Middleware, that is to say, the demo will not explain too much about the new files added under the reducers, components and containers files. If you do not understand, You can go back and parse the first update again.
Add the following code to actions/types.js
// Request a list of postsexport const REQUEST_POSTS = 'REQUEST_POSTS'; // The post returns dataexport const RECEIVE_POSTS = 'RECEIVE_POSTS'; // Switch data sourcesexport const SELECT_SUBREDDIT = 'SELECT_SUBREDDIT'; // Invalidate the cacheexport const INVALIDATE_SUBREDDIT = 'INVALIDATE_SUBREDDIT';
Copy the code
The following code is added to actions/index.js
export const selectSubreddit = subreddit => ({
type: SELECT_SUBREDDIT,
subreddit
});
export const invalidateSubreddit = subreddit => ({
type: INVALIDATE_SUBREDDIT,
subreddit
});
export const requestPosts = subreddit => ({
type: REQUEST_POSTS,
subreddit
});
export const receivePosts = (subreddit, json) => ({
type: RECEIVE_POSTS, subreddit, posts: json.data, receivedAt: Date.now() }); Const fetchPosts = subreddit => dispatch => {// API sends a request dispatch(requestPosts(subreddit));return fetch(`http://localhost:8081/data/${subreddit}.json`)
.then(response => response.json())
.then(json => {
setTimeout(()=>{// Use API to request results to update application state dispatch(receivePosts(subreddit, json))},2000); })}; const shouldFetchPosts = (state, subreddit) => { const posts = state.postsBySubreddit[subreddit];if(! posts) {return true
}
if (posts.isFetching) {
return false
}
return posts.didInvalidate
};
export const fetchPostsIfNeeded = subreddit => (dispatch, getState) => {
if (shouldFetchPosts(getState(), subreddit)) {
return dispatch(fetchPosts(subreddit))
}
};
Copy the code
Interpretation of the
The main points to note above are
fetchPosts
Returns a function while normalAction create function
An object is returned by default.- The argument to the function returned is
dispatch
andgetState
The twoRedux
Method, ordinaryAction create function
The parameter isAction
The content of the.- Of the returned functions, emit one
Action
: dispatch(requestPosts(subreddit)), indicating that the operation starts.- After the asynchronous operation is complete, issue another
Action
: receivePosts(subreddit, json)Is displayed, indicating that the operation is complete.
Data source description in Demo:
I originally intended to use the official Reddit Demo API, but finally found that the demo data provided by the official would report an error, so I used local JSON data and delayed the loading process of network API by two seconds.
App.js
import React, { Component } from 'react'
import { applyMiddleware, createStore } from 'redux'
import { createLogger } from 'redux-logger'
import { Provider } from 'react-redux'
import thunk from 'redux-thunk'
import LoadPosts from './js/containers/LoadPosts'
import rootReducer from './js/reducers'
export default class App extends Component {
render() {
const logger = createLogger();
const store = createStore(
rootReducer,
applyMiddleware(thunk, logger)
);
return( <Provider store={store}> <LoadPosts/> </Provider> ); }}Copy the code
Interpretation of the
CreateStore now has a different parameter for applyMiddleware(Thunk, Logger). For those of you who understand the first update, you can see that the Action is sent by the store.dispatch method. In normal cases, the parameters of the store.dispatch method can only be objects, not functions. To solve this problem, the middleware Redux-thunk is used to modify store.dispatch to accept functions as arguments.
Pay attention to
Some middleware have order requirements, check the documentation before using it. For example, logger must be placed last, otherwise the output will be incorrect.
This is the end of this writing.
~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️
⭐️⭐ ⭐ ⭐ ⭐️⭐ ⭐ ⭐️⭐️ disk disk disk disk disk disk disk disk disk disk disk disk disk
~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️ ~ ️
If you’ve used older versions of React Native, you know that before react navigation came along, most developers used the official Navigator. Until react Native V0.44.3 announced that Navigator had been abandoned.
Navigator
react-navigation
-
react navigation
It’s officially recommended, available at 🌟 on Github and maintained by the React Native community. It’s currently the most popular React Native navigation library. It is written entirely in JavaScript, rather than using native apis, and it recreates some subsets. This option allows users to customize any part of the navigation experience without having to learn iOS or Android navigation logic. Since most of the React Navigation logic runs in JavaScript rather than native, anything that blocks the JavaScript thread will cause stuttering. React Navigation v1 is quite different from v2. If you want to know the children’s shoes can see in front of me to write this article [react native powerful navigation V2.0 +] (www.jianshu.com/p/05fd0e9bc)… .
At present, it has been clearly stated in official documents:
Warning: in the next major version of React Navigation, to be released in Fall 2018, we will no longer provide any information about how to integrate with Redux and it may cease to work. Issues related to Redux that are posted on the React Navigation issue tracker will be immediately closed. Redux integration may continue to work but it will not be tested against or considered when making any design decisions for the library.
Some folks like to have their navigation state stored in the same place as the rest of their application state. Think twice before you consider doing this, there is an incredibly good chance that you do not need to do this!. Storing your React Navigation state in your own Redux store is likely to give you a very difficult time if you don’t know what you’re doing.
If your only reason for doing this is that you want to be able to perform navigation actions from outside of your components (eg: from a Redux middleware), you can learn more about this in navigating without the navigation prop.
Translation:
Warning: In the next major release of React Navigation, due in fall 2018, we will no longer provide any information on how to integrate Redux, and it may be discontinued. Redux issues posted in React Navigation Issue tracker will also be closed immediately. The Redux integration may continue to work, but will not be tested or considered when making any design decisions for the Library.
Some people like to store their navigation state in the same location as other applications’ state.Think twice before you consider doing this, but there’s a very good chance you don’t need to!. Storing React Navigation State in your own Redux store can be difficult if you don’t know what to do.
If the only reason you are doing this is to be able to perform navigation operations from outside the component (for example, from Redux middleware), you can learn more about thisDo not use Navigation prop for navigationThe information.
React Navigation will not be specifically compatible with Redux in the next release, it can be used, but it needs to be fixed.
Well, I don’t understand why the authorities want to do this, probably to reduce maintenance costs, but it is definitely not a wise choice, and there may be surprises, for now look forward to it. I personally would not recommend using React Navigation if redux is integrated in a project.
-
react-native-router-flux
It is based on React Navigation, but provides a different API for interacting with it. There is 7600+ 🌟 on Github, which allows you to define scene transformations in a central location without passing navigator objects, and can be easily accessed anywhere in the code.
The latest beta version, version 4, introduces, among other changes, drawer support and moB-X-driven navigational state machines that separate navigational logic from the presentation layer.
-
react-native-navigation
Another popular Navigation library is React Native Navigation developed by the Wix open source team, which is close to 9000+ 🌟 on Github. Its biggest advantage is 100% Native platform Navigation with cross-platform interface coverage, with Redux support out of the box.
You need to configure this package separately for iOS and Android, which includes linking to the iOS library, updating the iOS header search path, extending SplashActivity instead of ReactActivity in Android MainActivity, and several other steps detailed in the documentation. When you’re done, you just need to register the screens of all the applications and start the application.
At present, official documents also put forward:
Note: example redux is deprecated. Since we did not have enough time and resources to maintain both example projects, we decided to stop maintaining the redux example. This does not mean redux can’t be used with react-native-navigation (In fact, we use redux in the Wix app). For a working example project which uses redux with RNN you can refer to JuneDomingo/movieapp.
Translation:
Note: Using the example redux is not recommended. Since we did not have enough time or resources to maintain the two sample projects, we decided to stop maintaining the Redux sample. This does not mean redux cannot be used with React-native navigation (in fact, we use Redux in Wix applications). For a working example project that uses Redux with RNN, you can refer to JuneDomingo/Movieapp.
To sum up: personally speaking, fromreact navigation
和 react-native-navigation
The official toRedux
The attitude is totally different, at leastWix
In internal useRedux
. If needed in the projectRedux
My first choice would beReact Native Navigation
Because it’s a pure native experience, and yesRedux
The support is good. If not in useRedux
You can try the first two types of navigation in the project. These two types of navigation experience are also good, very close to the native experience.
Structure analysis
This article chooses to use React-native navigation. Please refer to the official documentation for the integration and API usage of React-native navigation. If you want to know how to use Redux in React Navigation, click here or here. Here is the new file code index.js
//discard import {AppRegistry} from'react-native';
AppRegistry.registerComponent('ReduxForReactNativeDemo', () => App);
Copy the code
//new
import App from './App';
new App();
Copy the code
App.js
import React, { Component } from 'react'
import { applyMiddleware, createStore } from 'redux'
import { createLogger } from 'redux-logger'
import { Provider } from 'react-redux'
import thunk from 'redux-thunk'
import rootReducer from './js/reducers'
import { Navigation } from 'react-native-navigation'
import { registerScreens } from './js/components/screens'
const logger = createLogger();
const store = createStore(
rootReducer,
applyMiddleware(thunk, logger)
);
registerScreens(store, Provider);
export default class App extends Component {
constructor(props){
super(props);
this._startApp();
}
_startApp = () => {
Navigation.startTabBasedApp({
tabs: [
{
label: 'Home',
screen: 'ReduxForReactNativeDemo.HomeScreen',
icon: require('./res/img/ic_home.png'),
// selectedIcon: require('./img/checkmark.png'),
title: 'Home',
overrideBackPress: false,
navigatorStyle: {}
},
{
label: 'Posts',
screen: 'ReduxForReactNativeDemo.PostsScreen',
icon: require('./res/img/ic_news.png'),
// selectedIcon: require('./img/checkmark.png'),
title: 'Posts', navigatorStyle: {} } ] }); }}Copy the code
Compared to the last versiondemo
And the wholeApp.js
The file code is basically changed
Other changes
Under the Components directory, the Screens directory is newly added. Under this folder, there are interface files one by one, and each interface is composed of multiple components.
Group.js
renamedHomeScreen.js
.- new
PostsDetail.js
,PostsScreen.js
,index.js
.index.js
File is used to register all interface files. Posts.js
newitem
Click the event, click to enter the list details interface.LoadPosts.js
68
Line new{... this.props}
, in order toPosts.js
You can go throughthis.props
Access to thenavigator
.- Added in the root directory
res
Resources folder.
Conclusion:
This structural analysis is here, say the next three demo version coherent to do down the feeling. To be honest, I learned a lot this time. I also encountered various problems in the process of practice. I consulted a large number of resources and had many questions. I have seen a lot of strange demo writing methods, rarely see the standard project engineering structure, most of them are for the purpose of achieving the effect, and can not use this project structure in the actual project, I introduced at the beginning of my article why I spend the time and energy to write this technical article. I will apply this engineering structure to future projects that integrate Redux. Finding a good learning material is really not easy, if you also feel good, might as well light up ❤️, let more people find it.
eggs
Attached demo, welcome ❤️⭐️👏 to point out mistakes or release their own opinions to explore, mutual encouragement. 🤝
Pay attention to
If you clone the latest version of the demo and run it with git tag, you can see that the demo has three tags. If you switch to the root directory and run the git tag, you can see that the demo has three tags.
Switch to the v0.1
Git checkout -b dev v0.1
Switch to the v0.2
Git checkout -b dev v0.2