美文网首页
理解React-redux模型并创建React项目

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

作者: ogood | 来源:发表于2019-02-15 11:42 被阅读0次

    理解React模型

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


    image.png

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

    理解React-Redux

    image.png

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

    生命周期

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


    image.png

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


    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   <div>this is an empty page</div>
        }
    }
    function App(props){
    
        return  ( 
        <Router history={history}>
    <React.Fragment>
        <NavBar/>
        <Switch>
        <Route exact path="/" component={HomePage}/>
        <Route path="/user/login" component={LoginPage}/>
        <Route path="/portfolio" component={()=><RestrictedPage><PortfolioPage/></RestrictedPage>}/>
        <Route path="/factor" component={ ()=><RestrictedPage><FilterEditor/></RestrictedPage>} />
    
        </Switch>
        </React.Fragment>
      </Router>
      )
    }
    
    ReactDOM.render(
        <Provider store={store}>
        <App />
    </Provider>, 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项目

          本文链接:https://www.haomeiwen.com/subject/xhdpeqtx.html