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
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
- redux: https://www.redux.org.cn/
- redux-saga: https://redux-saga-in-chinese.js.org/
- js-base64: https://www.npmjs.com/package/js-base64
- react-router: http://react-router.docschina.org/