React + react router + react Redux family bucket small project development process sharing



Project address:…


Finished downloading project

npm install


npm run devthat will do

be based onreact react-router reduxThe project is mainly to learn practical combatreact。 The data is fixed. It is temporarily caught from the hungry interface and simulates one0-100msAsynchronous data latency, thank you. Are you hungry.

The following contents are the process and some thoughts of project development. According to this process, at least a relatively complete project can be realizedreactFamily bucket project

Content reference


react-routerDocument address:…

react-routerChinese version reference:…

reduxDocument reference:

reduxChinese documents:

Construction project:

Create the project directory, install package.json, and configure webpack.config
Do a good job in basic dependency, which is extracted from package.json

    "devDependencies": {
        "babel-core": "^6.23.1",
        "babel-loader": "^6.4.0",
        "babel-preset-es2015": "^6.22.0",
        "babel-preset-react": "^6.23.0",
        "html-webpack-plugin": "^2.28.0",
        "jshint": "^2.9.4",
        "jshint-loader": "^0.8.4",
        "react": "^15.2.0",
        "react-dom": "^15.2.0",
        "react-router": "^2.0.0",
        "redux": "^3.6.0",
        "webpack": "^2.2.1",
        "webpack-dev-server": "^2.4.1"

The project module structure organizes some basic work

In addition to the technical selection, there are many basic things to be designed before starting the development of a project. A good organizational design can improve the work efficiency for the future. I still have many deficiencies in this aspect. At present, I mainly consider the design of three modules:

1: Background interface communication layer:model.jsIt mainly handles the request sending and callback of the unified interface, which is more conducive to later maintenance and readability

//The URL corresponding to the interface. This is only for demonstration
    const uris = {
          index_entry : fetchData.index_entry,
          hot_search_words : fetchData.hot_search_words
    //Interface call layer
    export default function send(url,postData,successCallback,errCallback){
        //Analog delay, dummy interface
        let promise = new Promise(function(resolve,reject){

2: Local data cache maintenance:baseStore.jsIt mainly deals with the jump and return between pages to increase more autonomy and expansibility

//Automatically store browsing records
    export function  saveFrom(prop) {
          let name = prop.pagename,
              transit =  prop.location,
              Qhfrom = transit.query.qhfrom, // all return to the home page by default
              para = transit.query.para ? JSON.parse(transit.query.para) : '';
          if(!qhfrom) return false;
          let paths  = localStorage.getItem("FromUrlStore") ? JSON.parse(localStorage.getItem("FromUrlStore")) : {};
          if (localStorage) {
            paths[name] = {
              'name': qhfrom, // store source page
              'para': para // stores the parameters of the source page
            localStorage.setItem("FromUrlStore", JSON.stringify(paths));
   //The source of the stored page is managed uniformly

3: Treatment of common methods:baseFun.jsIt is mainly used to define some common module methods

//Place common function 
    export function showToast(){

Use react router to initialize the page

import React from 'react'
     import { render } from 'react-dom'
     import { Router, Route, Link,hashHistory ,IndexRedirect,IndexRoute} from 'react-router'
     import Home from './components/home.jsx'
     import Discover from './components/discover.jsx'
     const App = React.createClass({
       render() {
         return (
                 < link to = "/ home" > takeout < / link > 
                 < link to = "/ discover? Qhfrom = home" > discover < / link >
     const route = (
          <Router history={hashHistory}>
             <Route path="/" component={App}>
               <IndexRoute component={Home} />
               <Route path="home" component={Home} />
               <Route path="discover" component={Discover} />
     render(route, document.getElementById("app"))

Brief introduction to code:
Because there is no background, thehashHistoryhashRouting), abouthashFor routing, refer to:…There is a brief introduction.

This is the router's jump < link to = "/ home" > takeout < / link >
This is to load the sub routing component {this. Props. Children}
This is the default jump page < indexroute component = {home} / >

Process the scrolling list of the first page

The home page is mainly divided into four components
Bottom navigation + scroll list + single product + home page search box

Scrolling lists encapsulate a simple component

        List = {Pro} // item component of each product
        Pagename = {'home'} // jump to the parent page of the product list to process the returned
        Data = {this. State. Productlist} // data to be rendered
        Onscroll = {this. Getmore. Bind (this)} // scroll load function
    In the scrolllist component, the scrolling event is monitored for automatic loading

React Redux handles login and logout

Reasons for using Redux: user information and login are two different components, and there is no parent-child relationship, but data status sharing and mutual influence are required. For details, please refer to the official documents above. I’ll briefly talk about the application of this project.

Define constantsactionTypes.js

//Login successful
    export const LOG_SUCCESS = 'LOG_SUCCESS'
    //Logging in
    export const LOG_ING = 'LOG_ING'
    //Logout login
    export const LOG_OUT = 'LOG_OUT'
    //It is mainly the name corresponding to the unified save status

Define specific trigger operationsactions/login.js

//Logoff synchronization
    export function log_out (){
        return {
    //Login asynchrony
    export function log_in (obj){
        return dispatch=>{
            //Pending status of login in progress
            //Start sending asynchronous login request
            new Promise((resolve,reject)=>{
    //Asynchronous state requires middleware

Processing datareducers/login.js

export default function(state = initialData,action){
            case actionTypes.LOG_SUCCESS:
                return {
            case actionTypes.LOG_ING:
                    Username: 'logging in'
            case actionTypes.LOG_OUT:
                return initialData
            default :
                return initialData  

Create a store layer using middlewarestore/store.js

import {createStore, applyMiddleware} from 'redux'
    import thunk from 'redux-thunk'
    //Combined multiple reducers, decoupling
    import rootReducer from '../reducers/index.js'
    const middlewares = [thunk]
    const createStoreWithMiddleware = applyMiddleware(...middlewares)(createStore)
    export default function configureStore(initialState){
        return createStoreWithMiddleware(rootReducer,initialState)

Introduce in routing layer

    import {Provider} from 'react-redux'
    const store = configureStore()
    const route = (
      <Provider store={store}>
          <Router history={hashHistory}>

Used in components

import { connect } from 'react-redux'
    Import {log_out} from '.. /.. / actions / login. JS' // operation
    function mapStateToProps(userinfo){
        Let {login} = userinfo // this is all the reducers returned. We only need the reducers currently. Refer to reducers / index.js
        return login
    export default connect(mapStateToProps)(UserInfo)
    //At this time, the login data can be obtained at this.props in the current component state,
    //When operating  
    const {dispatch} = this.props;
    //At this time, the data in Redux status can be operated, and each data change will be distributed to all received components

Above, we used many things to complete a simple small project