Redux state management methods and examples

Source: Internet
Author: User

State management is an integral part of building a single page application, and it is also a point of knowledge that is worth taking time to learn. React officially recommends that we use Redux to manage our react applications, as well as provide redux documentation for us to learn, with the Chinese address http://cn.redux.js.org/index.html

Objective

Although the official documentation says it takes only a few minutes to get started with Redux, I personally think that even if you look at a two or three days, you may not be able to get started, because the knowledge in the document is not only a lot of information, but also difficult to understand, not combined with some examples to find it difficult to use in real projects.

But do not worry that they will not learn, this is not I will bring you this dry, but also I learn redux experience.

If you are not familiar with how to build a React single page application, you can first move to my previous article, "React building a single page application method and example."

So below I will show you how to use Redux to manage your React project, and here I mainly teach you to build based on React + Redux + React-router method, this is the official document introduced in the relatively few but the project is necessary knowledge points.

Project directory

First, a project directory based on React + Redux + react-router can be built according to the pictures below me:

Where the assets directory is used to store static resources for the project, such as css/images, the SRC directory is used to store react component resources.

Portal File Configuration

In the Webpack configuration item, we need one or more entry files, here I will not show about Package.json and webpack.config.js file configuration, finally I will provide the entire project download link for your reference. Here I mainly introduce the next entry file index.js configuration instructions.

Import React from ' React '//introduction of ReactImport {render} from ' React-dom '//introducing the Render methodImport {Provider} from ' React-redux '//using provider allows our store to be used for the following componentsImport {Router, browserhistory} from ' React-router '//Browser history is recommended by React Router to create a browser appImport {Synchistorywithstore} from ' React-router-redux '//With the Synchistorywithstore provided by React-router-redux we can synchronize the navigation events with the storeImport Finalcreatestore from'./src/store/configurestore '//introducing the Enhanced storeImport DevTools from './src/containers/devtools '//Introducing the Redux debugging tool DevtoolsImport reducer from './src/reducers '//Introducing the Reducers collectionImport routes from './src/routes '//Introducing Routing ConfigurationImport'./assets/css/bootstrap.min.css '//Introducing Style Files//incoming reducer to the enhanced storeConst STORE =Finalcreatestore (Reducer)//create an enhanced version of history to synchronize navigation events with the storeConst HISTORY =Synchistorywithstore (Browserhistory, store) render ({/*using the provider Package page*/}    <provider store={store}> <div>            {/*Render Root Route*/}            <router history={history} routes={routes}/> {/*Rendering Debugging Components*/}            <devtools/> </div> </provider>, document.getElementById (' Mount '))

In the portal file we try to keep only the basic things, the rest of the configuration code we can put in the corresponding configuration file, such as routing, reducers and store configuration. Here I have placed them in a separate JS, only in the portal file through import, so management and maintenance will be very convenient, but will also increase the difficulty of understanding, but once you get started it will be easy. So let's take a look at the store configuration next.

Store configuration
Import thunk from ' Redux-thunk '//Redux-thunk supports dispatch function, and it can be called asynchronouslyImport Createlogger from ' Redux-logger '//print logs with Redux-loggerImport {createstore, Applymiddleware, compose} from ' Redux '//introduction of Redux CreateStore, middleware and composeImport DevTools from '. /containers/devtools '//Introducing the Devtools Debug component//Call Log Printing methodConst LOGGERMIDDLEWARE =Createlogger ()//Create a Middleware collectionCONST MIDDLEWARE =[Thunk, Loggermiddleware]//use compose to enhance the store, which is used with Applymiddleware and Redux-devtoolsConst Finalcreatestore =Compose (Applymiddleware (... middleware), devtools.instrument (),) (createstore) exportdefaultFinalcreatestore

Here we need to understand the concept of middleware (middleware). Middleware refers to code that can be embedded in the framework to receive requests to generate a response, and you can use multiple independent third-party middleware in a project, such as the Redux-thunk and Redux-logger above. For more information, please refer to the official documentation:
Http://cn.redux.js.org/docs/advanced/Mid ...

Routing configuration

In the above portal file configuration We put the Routing configuration section separately in the Routes.js file, here we look at its configuration:

 import React from ' React '  introduce React  Import {Route, indexroute} from ' React-router ' //  introduce react route  import {App, Home, Foo, Bar, antd} from './containers ' 

The routing configuration here is the same as when you are not using Redux, and the only thing you need to know is the concept of container components and presentation components. The components that are loaded in the route in the above configuration file can be considered container components.
(1) As the name implies, the display component is contained in the container component, only as a page display, does not define how the data read how to change, only through This.props accept data and callback function;
(2) The container component contains data for each presentation component, props, which provides data and methods for presentation components or other components.
We should put them in different folders to show the difference, such as the containers and Components folders in the "project directory" above contain the container component and the presentation component respectively. Specific instructions can refer to the article: HTTP://WWW.JIANSHU.COM/P/6FA2B21F5DF3

Root Component Configuration
Import React, {Component} from ' React '//introduction of ReactImport {Link} from ' React-router '//introducing link to handle navigation jumpsExportdefaultclass App extends Component {render () {return ( <div> <nav classname= "NavBar navbar-default" > <div classname= "container-f Luid "> <div classname=" Navbar-header "> <span classname=" Navb Ar-brand "href=" # "> <link to="/">Redux</Link> &lt                            ;/span> </div> <ul classname= "Nav navbar-nav" > <li> <link to= "/index" Activestyle={{color: ' #555 ', BackgroundColor:                                ' #e7e7e7 '}}> counters </Link> </li> <li>                            <link to= "/foo" Activestyle={{color: ' #555 ', backgroundcolor: ' #e7e7e7 '}}> static data </Link> </li> <li> <link to= "/bar" a Ctivestyle={{color: ' #555 ', BackgroundColor: ' #e7e7e7 '}}> Dynamic Data </Link> </li> &L t;li> <link to= "/antd" Activestyle={{color: ' #555 ', backgroundcolor: ' #e7e7e7 '}}> knot Hopewell antd</link> </li> </ul> &LT;/DIV&G                T </nav> <div classname= "Panel Panel-default" > <div classname= "panel-body" & Gt                        {  This. Props.children}</div> </div> </div>        )    }}

The entire root component App.js mainly renders the navigation and variable areas of the entire application, which is not actually related to redux. Note that the URL address in to must be the same as the path address name in Routes.js.

Writing here has not introduced Redux in the action and reducer configuration, then the next to introduce.

Action Configuration
Import {increase, decrease, getsuccess, refreshdata} from '. /constants '//introduce the action type name constantImport ' Whatwg-fetch '//can introduce fetch for Ajax//The method here returns an Action objectExport const INCREASE = n = {    return{type:increase, amount:n}}export const decrease= n + = {    return{type:decrease, amount:n}}export const RefreshData= () + = {    return{type:refreshdata}}export const getsuccess= (JSON) = = {    return{type:getsuccess, JSON}}functionfetchposts () {returnDispatch = {        returnFetch (' Data.json '). Then (RES)= = {Console.log (res.status);returnRes.json ()}) . then (data)={Dispatch (Getsuccess (data)}).Catch(e) ={console.log (E.message)})}}//The method here returns a function for asynchronous operationExportfunctionfetchpostsifneeded () {//Note that this function also receives the GetState () method    //it gives you a choice of what to dispatch next .    return(Dispatch, getState) = {        returnDispatch (Fetchposts ())}}

The method that returns an action object above is called the action creation function, which is the method that generates the action and is the only source of the store data.
The method that returns a function above is called "Asynchronous action", here is using Redux Thunk middleware, want to introduce redux-thunk this specialized library can use, so we can implement asynchronous Ajax request change state and so on function.

Reducer Configuration
//Reducers/count.jsImport {increase, decrease, getsuccess, refreshdata} from '. /constants '//introduce the action type constant name//Initialize state dataConst INITIALSTATE ={number:1, lists: [{text:The state of the entire application is stored in an object tree, and the object tree exists only in the only store. ‘}, {text:' The only way to change state is to trigger action,action is a normal object that describes an event that has occurred. ‘}, {text:To describe how action changes the state tree, you need to write reducers. ‘}, {text:' That's it, now you should understand what's going on with Redux. ‘}], data: []}//Enter by dispatch actionExportdefault functionUpdate (state =Initialstate, Action) {    //update state with different action type    Switch(action.type) { CaseIncrease:returnObject.assign ({}, state, {number:state.number +Action.amount}) Break         CaseDecrease:returnObject.assign ({}, state, {number:state.number-Action.amount}) Break         Casegetsuccess:returnobject.assign ({}, state, {Data:action.json}) CaseRefreshData:returnobject.assign ({}, state, {data: []})default:            returnState }}
// Reducers/index.js // merging reducers with Combinereducers // merging Routerreducer with management // introduce update this reducer  default  combinereducers ({    update,    routing:routerreducer})

Here we mainly need to understand how to merge the reducers through Combinereducers, and we must return a state's processing result after entering the Reducer method, or we will get an error. Also note that when merging reducers, it is necessary to add routerreducer, the reducer provided by "React-router-redux", to manage the status updates of the routes.

Container components

The difference and meaning between container components and presentation components is mentioned above, and here we need to use connect with Redux for state management in container components, which is a critical step.

Import React, {Component, proptypes} from ' React '//introduction of ReactImport {Connect} from ' React-redux '//Introducing ConnectImport List from '. /components/list '//Introducing the Display component listExportdefaultclass Foo extends Component {render () {//get the value to lists with This.propsconst {Lists} = This. Propsreturn(            <div> <ul classname= "List-group" >{Pass value to presentation component} {Lists.map ((e, index)= = <list Text={e.text} key={index}></list>                    )}                </ul> </div>        )    }}//Verify the parameter types in the componentFoo.proptypes ={lists:PropTypes.arrayOf (Proptypes.shape ({text:PropTypes.string.isRequired}). isrequired). isrequired }//get the lists value in stateConst GetList = state = = {    return{lists:state.update.lists}}//using connect to bind components to ReduxExportdefaultConnect (getList) (Foo)

We need to use connect when we need to get the initial state in the container component. Any component that is packaged from connect () can get a dispatch method as the props of the component and any content required in the global state. The only parameter to connect () is selector. This method can receive the global state from the Redux store, and then return the required props in the component. For details, please refer to the documentation: Http://cn.redux.js.org/docs/basics/Usage ...

Presentation components

A display component list is introduced in the container component above, so let's look at its code:

Import React, {Component, proptypes} from ' React 'default  class List extends Component {    render () {        return(            <li classname= "List-group-item" >{this .props.text}< /li>        )    = {    text:PropTypes.string.isRequired}

From this we can find that the display component does not have the method of connect, the data is obtained through the this.props, this way can be the data change is clear, easy to manage and maintain.

Demo Demos

Finally, let's take a look at this demo:

The entire demo code I uploaded to my github, need for children's shoes can be accessed: Https://github.com/luozhihao/redux-basic ... Download

Summarize

Redux a wide range of knowledge, here only to do a general introduction, the rest of the need for their own constant groping and practice. Hopefully this article will help you understand the general process of building a project with redux.

Sincerely salute

Original articles, reproduced please note from a radish a pit-blog Park [Http://www.cnblogs.com/luozhihao]

This address: http://www.cnblogs.com/luozhihao/p/5660496.html

This article was posted synchronously at: 1190000005933397

Redux state management methods and examples

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.