The long-awaited new tutorial is now available! Unlock new postures for React Native and Get the latest and hottest React Native technologies!

In order to help you learn how to use Redux in React Native, we will introduce how to use Redux in React Native. , as well as some basic and advanced knowledge.

This article references part of the lecture on React Native+Redux to learn more about React Native and Redux.

How to use Redux in React Native? ?

The preparatory work

Install the following components as required.

  • Redux (choice)
  • React-redux (mandatory) : redux library developed by the author of redux to facilitate the use of Redux on React;
  • Redux-devtools (optional) : The Redux developer tool supports hot loading, action replay, and custom UI.
  • Redux-thunk: Middleware for asynchronous actions;
  • Redux-persist (optional) : supports store local persistence.
  • Redux-observable (optional) : Implements cancelable actions;
npm install --save redux
npm install --save react-redux
npm install --save-dev redux-devtools
Copy the code

The react – story is introduced

React-redux is an official redux binding library. It is efficient and flexible.

View-layer binding introduces several concepts:

  • <Provider>Component: This component needs to be wrapped around the outermost layer of the component tree. This component makes it easy for all descendants of the root component to bind to the Store using the connect() method.
  • connect(): This is one method provided by react-Redux. If a component wants to respond to a change in state, it passes itself as an argument to the result of connect(). The Connect () method handles the details of the binding to the store and determines which part of the data in the binding store by selector.
  • selector: This is a function you wrote yourself. This function declares what part of the entire store your component needs as its props.
  • dispatchWhenever you want to change state in your application, you dispatch an action, which is the only way to change state.

React-redux provides the following apis:

  • Provider
  • connect

Provider

API prototype:

Enable connect() methods at the component level to get the Redux Store (passing the store to the App framework). Normally we need to nest the root component in a tag to use the connect() method.

class Index extends Component {
    render() {
        return  <Provider store={configureStore()}>
            <AppWithNavigationState />
        </Provider>}}Copy the code

The full portion of the above code snippet can be found in the course source code.

In the code above we wrap the tag around the root component AppWithNavigationState and then set it to store. Store (Redux Store) accepts the only Redux Store object in the application.

connect

Connect ([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])

Connect the React component to the Redux Store. The connect operation returns a new component class connected to the Redux Store. The connect operation does not change the original component class.

React-redux provides a connect function. Connect is a higher-order function that passes mapStateToProps, mapDispatchToProps, and wrapWithConnect to produce the Component. Passing the real Component as an argument to wrapWithConnect(MyComponent) produces a wrapped Connect Component, Such as: export default connect (mapStateToProps) (HomePage);

Using the step

  • Create an action

    /*
     * action 类型
     */
    
    export const ADD_TODO = 'ADD_TODO';
    export const COMPLETE_TODO = 'COMPLETE_TODO';
    export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER'
    
    /* * Other constants */
    
    export const VisibilityFilters = {
        SHOW_ALL: 'SHOW_ALL'.SHOW_COMPLETED: 'SHOW_COMPLETED'.SHOW_ACTIVE: 'SHOW_ACTIVE'
    };
    
    /* * action creates the function */
    
    export function addTodo(text) {
        return { type: ADD_TODO, text }
    }
    
    export function completeTodo(index) {
        return { type: COMPLETE_TODO, index }
    }
    
    export function setVisibilityFilter(filter) {
        return { type: SET_VISIBILITY_FILTER, filter }
    }
    Copy the code

    The full portion of the above code snippet can be found in the course source code.

  • Create the reducer

    import { combineReducers } from 'redux'
    import { ADD_TODO, COMPLETE_TODO, SET_VISIBILITY_FILTER, VisibilityFilters } from './actions'
    const { SHOW_ALL } = VisibilityFilters
    
    function visibilityFilter(state = SHOW_ALL, action) {
        switch (action.type) {
            case SET_VISIBILITY_FILTER:
                return action.filter
            default:
                return state
        }
    }
    
    function todos(state = [], action) {
        switch (action.type) {
            case ADD_TODO:
                return [
                    ...state,
                    {
                        text: action.text,
                        completed: false}]case COMPLETE_TODO:
                return [
                    ...state.slice(0, action.index),
                    Object.assign({}, state[action.index], {
                        completed: true
                    }),
                    ...state.slice(action.index + 1)]default:
                return state
        }
    }
    Merge multiple reducers into a rootReducer using combineReducers
    const todoApp = combineReducers({
        visibilityFilter,
        todos
    })
    
    export default todoApp
    Copy the code

    The full portion of the above code snippet can be found in the course source code.

Here, the combineReducers method provided by Redux is used to aggregate multiple reducer into a rootReducer.

  • Create the store

    import {createStore} from 'redux'
    import todoApp from './reducers'
    
    let store = createStore(todoApp)
    Copy the code

Here a store is created using the createStore method provided by Redux;

  • Wrap the root component with

    import {Provider} from 'react-redux'
    export default class index extends Component {
        render() {
            return (<Provider store={store}>
                <App/>
            </Provider>)}}Copy the code

The full portion of the above code snippet can be found in the course source code.

Here we use the provided by react-redux to wrap our root component so that all children of the root can bind to the store using the connect() method.

  • Packaging component:

    function selectTodos(todos, filter) {
        switch (filter) {
            case VisibilityFilters.SHOW_ALL:
                return todos
            case VisibilityFilters.SHOW_COMPLETED:
                return todos.filter(todo= > todo.completed)
            case VisibilityFilters.SHOW_ACTIVE:
                return todos.filter(todo= >! todo.completed) } }// Which props do we want to inject, given the global state?
    // Note: use https://github.com/faassen/reselect for better performance.
    function select(state) {
        return {
            visibleTodos: selectTodos(state.todos, state.visibilityFilter),
            visibilityFilter: state.visibilityFilter
        }
    }
    
    // Wrap component, inject dispatch and state into its default connect(select)(App);
    export default connect(select)(App)
    Copy the code

    The full portion of the above code snippet can be found in the course source code.

Using this code, we declare which part of the store the App component needs as props. Here we use connect. We pass select to Connect, and connect returns a function that generates the component. And then we pass the App component as an argument to this function.

Connect is a higher-order function that passes mapStateToProps, mapDispatchToProps, and returns a function that produces Component (wrapWithConnect). The real Component is then passed as an argument to wrapWithConnect(MyComponent), producing a wrapped Connect Component

  • Send (dispatch) action

       render() {
        // Injected by connect() call:
        const {dispatch, visibleTodos, visibilityFilter} = this.props
        return (
            <View>
                <AddTodo
                    onAddClick={text =>
                        dispatch(addTodo(text))
                    }
                    toast={this.toast}
                />
                <TabBar
                    filter={visibilityFilter}
                    onFilterChange={nextFilter =>
                        dispatch(setVisibilityFilter(nextFilter))
                    }/>
                <TodoList
                    todos={visibleTodos}
                    onTodoClick={index =>
                        dispatch(completeTodo(index))
                    }
                    toast={this._toast()}
                />
                <Toast ref={toast => this.toast = toast}/>
            </View>
        )
    }
    Copy the code

    The full portion of the above code snippet can be found in the course source code.

The Reducer creates a copy of the current state, modifies that copy and returns a new state, so the Store tree will be updated. The props of the corresponding component will then be updated, and the component will be updated;

conclusion

  • Redux apps have a single store. When splitting data processing logic, you should use a Reducer mix rather than create multiple stores;
  • One feature of Redux is state sharing. All states are placed in a store, and any Component can subscribe to the store.
  • Not all states are suitable to be placed in the store, which can make the store very large. For example, a state is used by only one component, there is no state sharing, and it can not be placed in the store.

To be continued

  • Redux development utility tutorial
  • React Native+Redux+ React-Navigation

reference

  • React Native+Redux builds a high-quality App
  • You may not need redux
  • React Native Redux Thunk vs Saga vs Observable
  • Redux 4 Ways
  • awesome-redux