Introduction notes for Redux and React-Router

Write in front, the author is shallow, write this article to do reference only! Please forgive me if I am wrong.

This article describes the basic usage of Redux and React-Router. Redux is a global state repository that can solve complex state relationships and manage them globally. React-Router is a React routing library that allows you to quickly add views and data streams to your application while keeping pages and urls in sync. Also, it’s highly recommended to read this article before reading it — React is a must-read for beginners;

Article code, please be patient to read, the author is also in order to better understand.

Redux

Redux is a JavaScript application for managing data state and UI state. With the increasing complexity of JavaScript single page application (SPA) development, JavaScript needs to manage more states than ever before, and Redux makes it easier to manage. (Redux supports React, Angular, jQuery, and even pure JavaScript)

Redux workflow

To make it easier to understand, I drew a picture of myself, as follows:

React Components is a borrower who borrows books from the librarian. The librarian finds the specific location in the library through Reducers library management software for easy search and then returns it to the borrower.

Reducers are spontaneous, as long as the Action is provided to the Store is automatically found

Use Redux

  • The installation
npm install --save redux
Copy the code
  • use
// Create a store folder in the SRC directory, and create an index.js file in that folder
// index.js is the store file for the entire project
import { createStore } from 'redux'  // Introduce the createStore method
const store = createStore()          // Create a datastore
export default store                 // Expose

// Create reducer.js in the same directory
const defaultState = {
  inputValue : 'Write Something'.list: ['Exercise'.'Keep reading']}export default (state = defaultState,action)=>{  // is a method function
    The Reducer accepts only state, but cannot change state
    return state
}
Copy the code
  • tool
Redux DevTools tools// Modify the store/index.js file
// Add a second parameter to createStore, as follows, and you can view the data parameters in the console
import { createStore } from 'redux'  // Introduce the createStore method
import reducer from './reducer'    
const store = createStore(reducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()) // Create a datastore
export default store   // Expose
Copy the code

case

Install ant – design

To make it easier to understand, the author made a case of optimizing Todolist. Install Ant-Design first:

npm install antd --save
Copy the code

If there is no demo project

// Install scaffolding tools first
npm install -g create-react-app
// Re-install the project
 D:  // Go to drive D
 create-react-app demo // Create the React project with scaffolding
 cd demo  // After the project is created, enter the project directory
 npm start  // Preview the project
Copy the code

Modify the components

Create a new component and import Input, Button, and List from the Ant component library.

import React, { Component } from 'react';
import 'antd/dist/antd.css' // Import styles
import { Input , Button , List } from 'antd'

const data=[
    'Morning meeting at 8:30 am to assign today's development work'.'Development requirements meeting with project Manager at 9am'.'5:30 PM review of today's code'
]

class TodoList extends Component {
    render() { 
        return ( 
            <div style={{margin:'10px'}} >
                <div>
                    <Input placeholder='write' style={{ width:'250px', marginRight:'10px'}} / >
                    <Button type="primary">increase</Button>
                </div>
                <div style={{margin:'10px',width:'300px'}} >
                    <List
                        bordered
                        dataSource={data}
                        renderItem={item= >(<List.Item>{item}</List.Item>)} / ></div>
            </div>); }}export default TodoList;
Copy the code

At this point, you can verify that it works. After running successfully, import to store.

import store from '.. /store/index';Copy the code

The use of the store

View the data in the Store (given default values earlier) from constructor.

constructor(props) {
  super(props);
  // Key code -----------start
  this.state = store.getState();
  // Key code -----------end
  console.log(this.state);
}
Copy the code

Modify the code in the component to use data from the Store

<div>
  <Input
    placeholder={this.state.inputValue}
    style={{ width: '250px', marginRight: '10px'}}onChange={this.onChangeInputValue}
    value={this.state.inputValue}
  />
  <Button type="primary" shape="round">increase</Button>
</div>
<div style={{ margin: '10px', width: '300px' }}>
  <List
    bordered
    dataSource={this.state.list}
    renderItem={(item)= > <List.Item>{item}</List.Item>} / ></div>

onChangeInputValue(e) {
  const action = {
    type: 'changeInput'.// A self-defined name
    value: e.target.value,
  };
  store.dispatch(action); // The action is created, but passed to the store via the dispatch() method
}
Copy the code

Define the onChangeInputValue method, and submit the action to the Store through dispatch(). The Store has an automatic push policy, which is processed by the Reducer.

Modify the reducer

// state: refers to the state in the original warehouse.
// Action: refers to the newly passed state of action.
export default (state = defaultState,action)=>{  // is a method function
    The Reducer accepts only state, but cannot change state.
    // Check if the method name is from you
    if(action.type === 'changeInput') {// Define a local variable
      let newState = JSON.parse(JSON.stringify(state)) // Deeply copy the state object
      newState.inputValue = action.value
      return newState
    }
    return state
}
Copy the code

Components to subscribe to

A component subscribes to the state of Redux while changing the value in the component;

constructor(props) {
  super(props);
  this.state = store.getState();
  this.storeChange = this.storeChange.bind(this); // To change the inputValue value
  store.subscribe(this.storeChange); // Subscribe to Redux status
}

storeChange() {
  this.setState(store.getState());
}
Copy the code

unsubscribe

// Unmount component, call this function when remove, general cancel, clear registered subscription, timer clean, cancel network request, operate in this
componentWillUnmount() {
    store.unsubscribe(this.storeChange); // Unsubscribe to clear up registered listeners
}
Copy the code

Story summary

  • A store is unique. There can only be one warehouse
  • Reducer cannot directly change the value in the store, so it defines a local variable to receive and return
  • The Store has an automatic push policy, which is processed by the Reducer

Flow: Submit the action in the component and pass it to the store via the dispatch() method; Then the store will be automatically sent to the reducer, and the reducer method returns after modification. Finally, subscribe to the state of Redux in the component, while modifying the value in the component;

React-Router

Use React-Router

  • The installation
npm install --save react-router-dom
Copy the code
  • use
// index.js
// First we rewrite the index.js code in the SRC file directory
import React from 'react';
import ReactDOM from 'react-dom'
import AppRouter from './AppRouter'

ReactDOM.render(<AppRouter/>.document.getElementById('root')   
Copy the code
// AppRouter.js
// The AppRouter component is not currently available, so we can create a file named AppRouter
import React from 'react';
// Use the react-router-dom package BrowserRouter Route Link
import {  BrowserRouter as Router, Route, Link } from 'react-router-dom';

import Index from './pages/Index'; / / component Index
import List from './pages/List';
import Home from './pages/Home';

function AppRouter() {
  return (
    <Router>
      <ul>
        <li>
          <Link to="/">Home page</Link>
        </li>
        <li>
          <Link to="/list/123">The list of</Link>
        </li>
      </ul>/* exact: the exact match must be /123 */}<Route path="/" exact component={Index}></Route>
      <Route path="/list/:id" component={List}></Route>
      <Route path="/home/" component={Home} />
    </Router>
  );
}

export default AppRouter;
Copy the code

Now that you know the basics of routing, look at how to implement nested routing.

Embedded routines by

Common background management will use nested routines, project directory structure:

- the SRC | - page | - videos | - workPlace | -- Index. Js / / component file name must be capital | -- videos. Js | -- workPlace. Js | -- Index. Js | -- AppRouter. JsCopy the code

There are two directories and three files under page; Directory to place the secondary routing component;

AppRouter.js

import React from 'react'; // imr
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
import './index.css';
import Index from './page/Index';
import Videos from './page/Videos';
import Workplace from './page/Workplace';
function AppRouter() {
  return (
    <Router>
      <div className="mainDiv">
        <div className="leftNav">
          <h3>The primary navigation</h3>
          <ul>
            <li>
              <Link to="/">Blog's front page</Link>
            </li>
            <li>
              <Link to="/videos/">Video tutorial</Link>
            </li>
            <li>
              <Link to="/workplace/">Workplace skills</Link>
            </li>
          </ul>
        </div>
        <div className="rightMain">
           <Route path="/" exact component={Index}></Route>
          <Route path="/videos/" component={Videos}></Route>
          <Route path="/workplace/" component={Workplace}></Route> 
        </div>
      </div>
    </Router>
  );
}

export default AppRouter;
Copy the code

Note that the Route tag path is lowercase and the Component property is uppercase.

Videos.js

import React from 'react';
import { Route , Link } from 'react-router-dom'
import  Angular from './videos/Angular'
import  ReactJs from './videos/ReactJs'
import  Vue from './videos/Vue'

function Video(){
  return (
    <div>
        <div className="topNav">
            <ul>
                <li><Link to="/videos/angular">Presents a tutorial</Link></li>
                <li><Link to="/videos/vue">Vue tutorial</Link></li>
                <li><Link to="/videos/reactJs">The React tutorial</Link></li>
            </ul>
        </div>
        <div className="videoContent">
            <div><h3>Video content</h3></div>
            <Route path="/videos/angular/"   component={Angular} />
            <Route path="/videos/vue/"   component={Vue} />
            <Route path="/videos/reactJs/"   component={ReactJs} />
        </div>
    </div>)}export default  Video
Copy the code

ReactJS.JS

import React, { Component } from 'react';

class ReactJs extends Component {
  constructor(props) {
    super(props);
    this.state = {  }
  }
  render() { 
    return ( <h1>I am the React</h1>); }}export default ReactJs;
Copy the code

Dynamic Routing

For ease of understanding, attach the complete code directly, where routeConfig is the list of permissions menu retrieved from the back end

import React from 'react'; // imr
import { BrowserRouter as Router, Route, Link } from 'react-router-dom';
import './index.css';
import Index from './pages/Index';
import Videos from './pages/Videos';
import Workplace from './pages/Workplace';
function AppRouter() {
  let routeConfig = [
    { path: '/'.title: 'Blog Home'.exact: true.component: Index },
    { path: '/videos/'.title: 'Video Tutorial'.exact: false.component: Videos },
    {
      path: '/workplace/'.title: 'Career Skills'.exact: false.component: Workplace,
    },
  ];
  return (
    <Router>
      <div className="mainDiv">
        <div className="leftNav">
          <h3>The primary navigation</h3>
          <ul>RouteConfig. Map ((item, index) => {return (routeConfig. Map (item, index) => {return (routeConfig. Map (item, index) => {return (routeConfig.<li>
                  <Link to={item.path}>{item.title}</Link>
                </li>
              );
            })}
          </ul>{/ *<ul>
            <li>
              <Link to="/">Blog's front page</Link>
            </li>
            <li>
              <Link to="/videos/">Video tutorial</Link>
            </li>
            <li>
              <Link to="/workplace/">Workplace skills</Link>
            </li>
          </ul>* /}</div>
        <div className="rightMain">
          {routeConfig.map((item, index) => {
            return (
              <Route
                path={item.path}
                exact={item.exact}
                component={item.component}
              ></Route>); })} {/ *<Route path="/" exact component={Index}></Route>
          <Route path="/videos/" component={Videos}></Route>
          <Route path="/workplace/" component={Workplace}></Route>* /}</div>
      </div>
    </Router>
  );
}

export default AppRouter;
Copy the code

Ending

Finally, this paper is just a study note, which is also some basic knowledge learned by the author through watching the technology fat video. It’s hard to keep going, but it’s even harder to keep going day after day! But I believe that if you work hard, there will be results, and the meaning of working hard is to see all the people and things you like.