理解React-redux模型并创建React项目

理解React模型

以往操作DOM一般通过原生JS或jQuery库,此方式随意、灵活,但当web界面越来越大,js文件越来越多,很叫人精疲力竭。React提出两大创新,一是组件化单向数据流思想,另一个是用虚拟DOM局部更新。


理解React-redux模型并创建React项目_第1张图片
image.png

如上图就是一个React组件的单向数据流。当用户执行某个操作,即触发此组件的某个方法,此方法可直接更新组件内State属性变量,也可以从远程服务器fetch数据再更新State。用户手动绑定State与DOM节点,当属性改变,React运行diff算法,根据shouldComponentUpdate返回值,确认是否应刷新此组件在DOM的展示。

理解React-Redux

理解React-redux模型并创建React项目_第2张图片
image.png

React-redux将State从组件中抽出,集中管理,便于组件之间共享变量。如上图就是Redux循环流。用户动作在抛出后被中间件捕获,同时也被Reducer捕获。中间件查找此事件是否有对应的函数动作,如有则执行函数,否则忽略。Reducer则根据事件,查找如何更改Store,如果有相应代码,则执行代码,更新Store,否则忽略。注意中间件也可以抛出事件,如redux-sagas,通常,用户动作触发事件被sagas捕获,sagas执行各种复杂代码,包括向远程服务器取数据,然后再抛出事件,被reducer捕获,然后更新store中对应的内容。

生命周期

function组件没有声明周期,React class组件有生命周期。以下图为新版


理解React-redux模型并创建React项目_第3张图片
image.png

老版本更新周期函数为以下四个。
componentWillMount
componentWillReceiveProps
shouldComponentUpdate
componentWillUpdate


理解React-redux模型并创建React项目_第4张图片
image.png

React 16.3起将componentWillReceiveProps变更为getDerivedStateFromProps,并添加getSnapshotBeforeUpdate,主要用于异步渲染。
详细可参考官网https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html

构建React项目

理解之后,就可以开始创建react app。分为:
构建npm项目
npm init
安装必要模块
npm install .....
npm install -D ....

//package.json
{
  "name": "portfolio",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --mode production",
    "start": "webpack-dev-server"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "antd": "^3.13.0",
    "react": "^16.7.0",
    "react-dom": "^16.7.0",
    "react-redux": "^6.0.0",
    "react-router": "^4.3.1",
    "react-router-dom": "^4.3.1",
    "redux": "^4.0.1",
    "redux-saga": "^0.16.2"
  },
  "devDependencies": {
    "@babel/core": "^7.2.2",
    "@babel/plugin-proposal-class-properties": "^7.2.3",
    "@babel/plugin-transform-runtime": "^7.2.0",
    "@babel/preset-env": "^7.2.3",
    "@babel/preset-react": "^7.0.0",
    "babel-loader": "^8.0.5",
    "css-loader": "^2.1.0",
    "html-webpack-plugin": "^3.2.0",
    "redux-devtools-extension": "^2.13.7",
    "style-loader": "^0.23.1",
    "webpack": "^4.28.4",
    "webpack-chunk-hash": "^0.6.0",
    "webpack-cli": "^3.2.1",
    "webpack-dev-server": "^3.1.14"
  }
}

由于react使用es6,有很多新特性,而大多数浏览器还不支持es6,所以还需要webpack进行转义。webpack除了转译功能,还支持本地webserver,文件分割,代码检查等,详细配置较多,以下是我自己的常用模板。

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
var webpack = require('webpack');
module.exports = {
  entry: './src/index.jsx',
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'static/js/[name].js',
    chunkFilename: 'static/js/[name].chunk.js',
    publicPath: '/',
  },
 mode:"development",
  module: {
    
    rules: [{
      test: /\.js|.jsx$/,
      exclude: path.resolve(__dirname, 'node_modules/'),
      use: {
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env','@babel/preset-react'],
          plugins:["@babel/plugin-proposal-class-properties","@babel/plugin-transform-runtime","@babel/plugin-syntax-dynamic-import"]
        },        
      }
    },{
      test: /\.css$/,
      loaders: [
        'style-loader',
        'css-loader',
       ],
    }]
  },
  resolve: {
    extensions: ['.js', '.jsx'],
  },
  plugins:[
    new webpack.HotModuleReplacementPlugin(),
    new HtmlWebpackPlugin({
      title: 'portfolio',
      template: path.join(__dirname, 'src', 'index.ejs'),
   //   favicon: path.join(__dirname, 'src', 'favicon.ico'),
      meta: [
        {
          name: 'description',
          content: 'simple website',
        },
      ],
      minify: {
        collapseWhitespace: true,
      },
    }),
],
optimization: {
  nodeEnv: 'development',
  splitChunks: {
    cacheGroups: {
      commons: {
        test: /[\\/]node_modules[\\/]/,
        name: 'vendors',
        chunks: 'all',
        minChunks: 2,
      },
      default: {
        minChunks: 2,
        reuseExistingChunk: true,
      },
    },
  },
},
  devServer: {
    contentBase: path.join(__dirname, "dist"),
    open:true, // 自动打开浏览器
    overlay: true,
    compress:true,
    inline:true,//inline模式热加载
    hot:true//开启热加载

}
};

编写react代码

以下为案例入口文件,包含一个简单HomePage组件,包含另一个整体组件App。App组件中,包含Router组件,可以根据URL匹配组件。RestrictedPage组件是高阶组件,将内部组件进一步封装,限定仅登陆用户可见。ReactDOM.render将react组件挂载到DOM页面,同时注入由Redux创建的store对象。

class HomePage extends Component{
    render(){
        return   
this is an empty page
} } function App(props){ return ( }/> } /> ) } ReactDOM.render( , document.getElementById('root'))

参考:
https://grokonez.com/frontend/react/react-component-lifecycle-methods-from-v16-3-react-lifecycle-example
https://reactjs.org/docs/code-splitting.html

你可能感兴趣的:(理解React-redux模型并创建React项目)