Template React project framework construction

Create a React project

1. Create a project

npx create-react-app demo(项目名称)
cd demo

2. Download dependencies

npm i antd node-sass --save

Use react-redux

1. Download dependencies

npm install redux react-redux redux-saga redux-devtools js-base64 --save

2. Directory structure

insert image description here

3. store

index.js

// createStore 创建store对象,保存state
// applyMiddleware 使用中间件
// compose 从右到左组合函数
import {
    
     createStore, applyMiddleware, compose } from "redux";
// createSagaMiddleware 创建saga对象
import createSagaMiddleware from 'redux-saga';
import {
    
     Base64 } from 'js-base64';
import reducers from './reducers';
import rootSaga from "./sagas";

const sagaMiddleware = createSagaMiddleware();

// 扩展浏览器工具
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;

// store 的默认值
let defaultState = {
    
    
  userInfo: {
    
    }
}

const localRedux = window.sessionStorage.getItem('redux');
if (localRedux) {
    
    
  defaultState = JSON.parse(Base64.decode(localRedux));
}

export default createStore(
  reducers,
  defaultState,
  composeEnhancers(
    applyMiddleware(sagaMiddleware)
  )
)

sagaMiddleware.run(rootSaga);

actions

action-type.js

Define action type constants, you can determine whether to use this file according to actual needs, if it is a large project, it is recommended to use.

export const LOGIN = 'LOGIN';
export const TEST1 = 'TEST1';
export const TEST2 = 'TEST2';
export const SAVA_USER_INFO = 'SAVA_USER_INFO';

index.js

import {
    
     SAVA_USER_INFO } from './action-type';

// 保存用户信息
export const saveUserInfo = (payload) => {
    
    
  return {
    
    
    type: SAVA_USER_INFO,
    payload
  }
}

reducers

index.js

import {
    
     combineReducers } from "redux";
import userInfo from "./userInfo";

export default combineReducers({
    
    
  userInfo
});

userInfo.js

import {
    
     SAVA_USER_INFO } from '../actions/action-type';

export default function(state={
     
     }, actions) {
    
    
  switch (actions.type) {
    
    
    case SAVA_USER_INFO: {
    
    
      return actions.payload;
    }
    default: {
    
    
      return state;
    }
  }
}

saga

index.js

redux-saga can handle asynchronous operations.

import {
    
     all } from 'redux-saga/effects';
import loginSaga from './loginSaga';
import testSaga from "./testSaga";

export default function* rootSaga() {
    
    
  yield all([
    loginSaga,
    testSaga
  ])
}

loginSaga.js

import {
    
     put, call, takeEvery } from 'redux-saga/effects';
import {
    
     LOGIN } from "../actions/action-type";

function* login(actions) {
    
    
  console.log('loginSaga:', actions);
}

export default function* () {
    
    
  yield takeEvery(LOGIN, login);
}

testSaga.js

import {
    
     put, call, takeEvery } from 'redux-saga/effects';
import {
    
     TEST1, TEST2 } from "../actions/action-type";

function* test1(actions) {
    
    
  console.log('test1Saga:', actions);
}

function* test2(actions) {
    
    
  console.log('test2Saga:', actions);
}

export default function* () {
    
    
  yield takeEvery(TEST1, test1);
  yield takeEvery(TEST2, test2);
}

4. Project import store

4.1 The root component mounts the store

src/ index.js

import React from 'react';
import ReactDOM from 'react-dom';
import {
    
     Provider } from "react-redux";
import './index.scss';
import App from './components/App';
import store from './redux';

ReactDOM.render(
  <Provider store={
    
    store}>
    <App />
  </Provider>,
  document.getElementById('root')
);

4.2 Use store in components

Take the App component as an example.

App/index.jsx

container component

import {
    
     connect } from "react-redux";
import App from './App';
import {
    
     saveUserInfo } from "../../redux/actions";

function mapStateToProps(state, ownerProps={
     
     }) {
    
    
  return {
    
    
    ...state,
    ...ownerProps
  }
}

function mapDispatchToProps(dispatch) {
    
    
  return {
    
    
    saveUserInfo: (userInfo = {
     
     }) => {
    
    
      dispatch(saveUserInfo(userInfo));
    }
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(App)

App/App.jsx

functional components

import React, {
    
     Component } from "react";
import {
    
     Button } from "antd";
import {
    
     Base64 } from "js-base64";
import './index.scss';


class App extends Component {
    
    

  componentDidMount() {
    
    
    window.addEventListener('beforeunload', this.handleBeforeUnload);
  }

  componentWillUnmount() {
    
    
    window.removeEventListener('beforeunload', this.handleBeforeUnload);
  }

  handleBeforeUnload = () => {
    
    
    const {
    
     userInfo } = this.props;
    window.sessionStorage.setItem('redux', Base64.encode(JSON.stringify({
    
     userInfo })))
  }

  render() {
    
    
    return (
      <div className="App">
        App Component
        <Button onClick={
    
    () => this.props.saveUserInfo({
    
    name: 'gaoli'})}>
        	保存用户信息
        </Button>
      </div>
    );
  }
}

export default App;

Use react-router

1. Download dependent files

npm i react-router-dom --save

2. src/index.js

import React from 'react';
import ReactDOM from 'react-dom';
import {
    
     Provider } from "react-redux";
import {
    
     BrowserRouter } from 'react-router-dom';
import './index.scss';
import App from './components/App';
import TestRouter from './components/TestRouter';
import store from './redux';

ReactDOM.render(
  <Provider store={
    
    store}>
    <BrowserRouter>
      <App />
      <TestRouter/>
    </BrowserRouter>
  </Provider>,
  document.getElementById('root')
);

document address

  1. redux: https://www.redux.org.cn/
  2. redux-saga: https://redux-saga-in-chinese.js.org/
  3. js-base64: https://www.npmjs.com/package/js-base64
  4. react-router: http://react-router.docschina.org/

Guess you like

Origin blog.csdn.net/qq_36968599/article/details/118760773