React has close to 70,000 stars on Github and is currently the most popular front-end framework. React+Redux React+Redux

React Practice Project (1) This practice code

Deployed url

Redux Redux Redux Redux Redux Redux Redux

Rudex

All states in an application are stored in a single store as a tree of objects. The only way to change state is to trigger an action, an object that describes what happens. To describe how an action changes the state tree, you need to write reducers.

Let’s start with the status management of login and registration

First create the redux folder in the SRC directory as follows

Digag ├ ─ ─ the README. Md ├ ─ ─ node_modules ├ ─ ─ package. The json ├ ─ ─ the gitignore ├ ─ ─ public │ └ ─ ─ the favicon. Ico │ └ ─ ─ index. The HTML │ └ ─ ─ Manifest.txt └── imp imp ── imp imp ── imp imp ── imp imp └ ─ ─ App └ ─ ─ App. Js └ ─ ─ App. CSS └ ─ ─ redux └ ─ ─ action └ ─ ─ the users. The js └ ─ ─ reducer └ ─ ─ auth. Js └ ─ ─ the users. The js └ ─ ─ sagas └ ─ ─ API. Js └ ─ ─ sagas. Js └ ─ ─ selectors. Js. Js └ ─ ─ the users. The js └ ─ ─ store └ ─ ─ store. Js └ ─ ─ App. Test, js └ ─ ─ index. The CSS └ ─ ─ index, js └ ─ ─ logo. SVG └ ─ ─ registerServiceWorker. JsCopy the code

The code is available here

Remember to update dependencies in package.json

I’ll start explaining the key code

  • action

    action/users.js
/* * action type */ export const REGISTER_USER = 'REGISTER_USER'; // omit other action types /* * action create function */ export const registerAction = (newUser) => {return{type:REGISTER_USER, data: newUser, } }; // omit other action creation functionsCopy the code
  • reducer

    reducer/users.js
//Immutable Data is Data that cannot be changed once created. // Any modification or addition or deletion of an Immutable object returns a new Immutable object. import Immutable from 'immutable'; Import {REGISTER_USER, REGISTER_USER_SUCCESS, REGISTER_USER_FAILURE} from '.. /action/users'; // Initialize state const initialState = Immutable. FromJS ({newUser: null, error: null, saveSuccess: false,}); Reducer is a pure function that accepts old states and actions and returns new states. export const users = (state = initialState, Action = {}) => {switch (action.type) {case REGISTER_USER: return state.merge({// update status 'newUser': action.data, 'saveSuccess': false, 'error': null, }); case REGISTER_USER_SUCCESS: return state.set('saveSuccess', action.data); case REGISTER_USER_FAILURE: return state.set('error', action.data); default: return state } };Copy the code
  • store

    store/store.js
import {createStore, combineReducers, applyMiddleware } from 'redux'; import createSagaMiddleware from 'redux-saga' import * as reducer from '.. /reducer/users'; import rootSaga from '.. /sagas/sagas'; const sagaMiddleware = createSagaMiddleware(); const store = createStore( combineReducers(reducer), applyMiddleware(sagaMiddleware) ); sagaMiddleware.run(rootSaga); export default store;Copy the code

Then use it in the entry filestore

src/index.js

import {Provider} from 'react-redux'; import store from './redux/store/store'; Reactdom.render (<Provider store={store}> <App /> </Provider>, document.getelementByid ('root'));Copy the code

Get the action and status in app.js

import {registerAction, loginAction} from '.. /.. /redux/action/users'; import {connect} from "react-redux"; import {bindActionCreators} from "redux"; Class App extends Component {render(){return(<div className="App"> // omit </div>)}} export default connect() State. Users indicates the users exported from the reducer/users.js file // Console.log (state); Return {users: state.users}}, (dispatch) => {return {// Create action registerActions: bindActionCreators(registerAction, dispatch), loginActions: bindActionCreators(loginAction, dispatch), } })(App); / / in the props of App components are enclosing props. Users enclosing props. RegisterActions enclosing props. LoginActions / / This.props. Users is Immutable, and this.props.users. Get ('newUser') // Can be a normal js object from the reducerCopy the code

Decorator version: The decorator decorator plug-in babel-plugin-transform-decorators-Legacy needs to be enabled in Babel

@connect(
  (state) => {
    console.log(state);
    return ({
      users: state.users,
    });
  },
  {registerActions: registerAction, loginActions: loginAction}
)
Copy the code

Finally, theregisterActionsTo the RegisterDialog child component,

src/components/Index/RegisterDialog.js

// omit other code handleSubmit = (e) => {e.preventDefault(); Refs.user.validate ((valid) => {if (valid) {// this.state.user user registration data collected for the form this.props.registerActions(this.state.user); this.setState({loading: true}); }}); };Copy the code

The process is:

  • Call to action

    this.props.registerActions(this.state.user);

    Return to action for
{
    type:REGISTER_USER,
    data: this.state.user,
}
Copy the code
  • Reducer updates the state based on the action type
switch (action.type) { case REGISTER_USER: return state.merge({ 'newUser': action.data, 'saveSuccess': false, 'error': null, }); // omit other codeCopy the code

At this point, the state newUser in our store is updated to be a synchronous action for the data collected in the registration popup, whereas registration is an asynchronous operation. The next article will show you how to use Redux-Saga for asynchronous operations. Redux-saga is already in use, and you can read the code for yourself.

Project code address: github.com/DigAg/digag… Vue2 version project code address: github.com/DigAg/digag… Corresponding back-end project code address: github.com/DigAg/digag…