react杂记

React

webpack+react (hello world)

项目结构:
    src:
        app.js
        main.js
    package.json
    webpack_dev_config.js

须要安装包:
    yarn add react react-dom --save

app.jscss

import React, {component} from 'react';
class App extends Component {
    render(){
        return (
            <div>
                hello world
            </div>
        )
    }
}
export default App

注意:html

return 最外一层的div不能破坏,内容所有写在div里面

浏览器不识别jsx,因此用babel来转换
见webpack_dev_config.js中的配置
网页地址:
    https://babeljs.cn/docs/setup/#installation

main.js(导入根组件,并渲染根组件)node

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App'
ReactDOM.render(
    <App />, document.getElementById('root'));

注意:react

若是App.js的导出是
    export App
则引入时应该是
    import {App} from 'xxxxx'

webpack_dev_config.jswebpack

配置babel:git

https://babeljs.cn/
https://babeljs.cn/docs/setup/#installation //详情看这个

1.  安装包
    yarn add babel-loader babel-core --dev 
    //转es6      
    yarn add babel-preset-env --dev
    //转换jsx,并添加 "react" 到你的 .babelrc 的 presets 数组中。
    yarn add babel-preset-react --dev

开发阶段:es6

网址:

    https://github.com/jantimon/html-webpack-plugin

结合webpack-dev-server 配合 html-webpack-plugin

1.  安装包
    yarn add webpack html-webpack-plugin webpack-dev-server --dev

代码:github

var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry: './src/main.js',
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: "babel-loader"
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: './template.html', 
            filename: 'index.html'
        })
    ]
}

package.jsonweb

配置scripts
    
    "scripts": {
        "dev": "webpack-dev-server --progress --open --config webpack_dev_config.js --prot 6008"
    }

.babelrcnpm

{
    "presets": [
        "env",
        "react"
    ]
}

脚手架

参考地址:
    https://doc.react-china.org/docs/installation.html

npm install -g create-react-app
create-react-app my-app

热更新(非脚手架项目)

参考地址:
    https://github.com/gaearon/react-hot-loader
1.  
    yarn add react-hot-loader --dev
    yarn add babel-polyfill --dev

2.  
    // .babelrc
    {
      "presets": [
            ["env",
            {
                "modules": false
            }],
            "react"
        ],
      "plugins": ["react-hot-loader/babel"]
    }
    
3.  
    https://webpack.js.org/guides/hot-module-replacement/#enabling-hmr

4.  
    // webpack.config.js
    module.exports = {
      entry: ['babel-polyfill', 'react-hot-loader/patch', './main.js'],
    }
    Note: Make sure to set the output.publicPath property to "/" as well. Otherwise hot reloading won't work as expected for nested routes.

5.
    // main.js
    import React from 'react'
    import ReactDOM from 'react-dom'
    import { AppContainer } from 'react-hot-loader'
    import App from './containers/App'
    
    const render = Component => {
      ReactDOM.render(
        <AppContainer>
          <Component />
        </AppContainer>,
        document.getElementById('root'),
      )
    }
    
    render(App)
    
    // Webpack Hot Module Replacement API
    if (module.hot) {
      module.hot.accept('./containers/App', () => {
        render(App)
      })
    }

    Note: To make this work, you'll need to opt out of Babel transpiling ES2015 modules by changing the Babel ES2015 preset to be ["es2015", { "modules": false }]

6.  
    "scripts": {
        "dev": "webpack-dev-server --progress --open --config webpack_config_dev.js --port 6008 --hotOnly"
    }

热更新(脚手架生成的项目)

只须要在根目录下运行npm run eject,目录结构会改变

https://github.com/gaearon/react-hot-loader

Migrating from create-react-app里面跟着作三步

React对css、less、sass处理

1.  直接在标签里经过style写
    1.  <div style={{color:'red'}}>
            hello world123
        </div>
        <span style={{ fontSize : 16 + "px"}}>Hello, yoona</span>;
    2.  放在单独的对象中
        const style = {
            color: 'green'
        }
        <div style={style}>
            hello world 
        </div>      

2.  经过外部样式来写
    import  'xxxx.css/xxx.less/xxx.sass'
    //须要安装loader
    // style-loader css-loader less-loader sass-loader node-sass(这个用cnpm装)
    //yarn add style-loader css-loader --dev

    <div className="xxxx">
            hello world123
    </div>


注意:
    在jsx中,属性名称后面的值,两种状况,一种字符串,一种{}

组件-----有状态组件,无状态组件

组件的数据来源于两部分
    1.  父组件
    2.  本身内部数据

无状态组件:
    本身内部没有数据,数据来源于父组件

有状态组件:
    便可有父组件数据,也能够有本身内部数据

无状态组件

语法:

    import React from 'react'
    function Hello (){
        return (
            <div>123</div>
        )
    }
    export default Hello
    
传值:

    传值方:
        经过属性名称=值的方式传递
        <Hello name="abc" age={10}></Hello>

    接收方:
        function Hello (props){
            return (
                <div>123,{props.name}</div>
            )
        }

注意:
    父组件传过来的值只能展现,不能直接修改

有状态组件

语法:

    class Welcome extends React.Component {
      render() {
        return <h1>Hello, {this.props.name}</h1>;
      }
    }

传值:

    传值方:
        经过属性名称=值的方式传递
        <Hello name="abc" age={10}></Hello>

    接收方:
        经过{this.props.name}

私有的值:
    constructor(){
        super()
        this.state = {
            name: 'tom'
        }
    }
    使用: {this.state.name}   

默认值(es7):
    包:babel-preset-stage-0
    .babelrc中添加"stage-0"

    static defaultProps = {
        initCount: 300
    }

调用函数

<button onClick={()=>{this.clickme()}}>点我</button>

clickme(){
    console.log(1)
}

<button onClick={this.clickme()}>点我</button>
这种绑定是拿不到this的

改变内部数据

this.setStatus({
    name: "yoona"
})

prop-types检查类型 15.0+以后

import PropTypes from 'prop-types'

static propTypes = {
    initCount: PropTypes.number/string
}

生命周期

componentWillMount(){}
render(){}
componentDidMount(){}
componentWillReceiveProps(){}
shouldComponentUpdate(){
    return true
}
componentWillUpdate(){}
componentDidUpdate(){}

集成 Ant-Design

参考地址:
    https://ant.design/docs/react/introduce-cn

1.  安装
    yarn add antd

2.  import { DatePicker } from 'antd'; 

3.  import 'antd/dist/antd.css';  // or 'antd/dist/antd.less'

按需导入:
    1.  // .babelrc or babel-loader option
        {
          "plugins": [
            ["import", { "libraryName": "antd", "libraryDirectory": "es", "style": "css" }] // `style: true` 会加载 less 文件
          ]
        }
        而后只需从 antd 引入模块便可,无需单独引入样式

        参考地址:https://github.com/ant-design/babel-plugin-import

    2.  手动按需导入
        import DatePicker from 'antd/lib/date-picker';
        // 加载 JS
        import 'antd/lib/date-picker/style/css';      
        // 加载 CSS

react-router-dom

参考地址:
    https://reacttraining.com/react-router/web/example/basic

yarn add react-router-dom --save

fetch-jsonp

yarn add fetch-jsonp --save

import fetchJsonp from 'fetch-jsonp'

getFilmList(){
     const url =  `https://api.douban.com/v2/movie/${this.state.filmType}`
     fetchJsonp(url).then(response=>response.json()).then(data=>{
         this.setState({
             isLoading: false,
             filmList: data.subjects
         })
     }).catch(e=> console.log('error',e))
}

改变数据时:

componentWillReceiveProps(props){
    this.setState({
        filmType: props.match.params.filmTypes,
        isLoading: true
    },()=>{
        this.getFilmList()
    })
}

render里面须要遍历时用{}

render() {
    if(this.state.isLoading){
        return <Spin tip="加载中...">
            <Alert
            message="正在加载中"
            description="哥正在拼命加载中,请稍后"
            type="info"
            />
        </Spin>
    }else{
        return (
            <div style={{display:'flex',flexWrap:'wrap',textAlign:'center'}}>
            {
                this.state.filmList.map((item,i)=>{
                    return <div key={i} onClick={()=>{this.goMovieDetail(item.id)}} className="movieItem" style={everyMovieItemStyle}>
                        <img style={{height:378}} src={item.images.small} alt=""/>
                        <p><strong>{item.title}</strong></p>
                        <p><strong>电影类型:{item.genres.join(',')}</strong></p>
                        <p><strong>上映年份:{item.year}</strong></p>
                        <div>评分:<Rate disabled defaultValue={item.rating.average / 2} /></div>
                    </div>
                })
            }
        </div>
        )
    }
}

改变导航

//经过编程式导航跳转到电影详情组件中去
goMovieDetail(movieId){
    this.props.history.push(`/movie/detail/${movieId}`)
}

//返回到上一级
goBack() {
    this.props.history.goBack()
}

webpack打包

参考地址(性能优化):
    https://doc.react-china.org/docs/optimizing-performance.html

webpack指南里面:    
    https://doc.webpack-china.org/guides/production/
    
1.  新建一个配置文件webpack_config_prod.js
2.  热重载要干掉
3.  压缩js
    new webpack.DefinePlugin({
        'process.env': {
            NODE_ENV: JSON.stringify('production')
        }
    }),
    new webpack.optimize.UglifyJsPlugin({
            compress: {
                warnings: false
            },
            comments: false     
    })
4.  压缩html
    参考网址:
        https://github.com/jantimon/html-webpack-plugin
        https://github.com/kangax/html-minifier#options-quick-reference

    new HtmlWebpackPlugin({
        template: './template.html', 
        filename: 'index.html',
        minify: {
            collapseWhitespace: true,
            removeComments: true,
            minifyCSS: true,
            minifyJS: true
        }
    })

5.  output

        const path = require('path');
        output: {
            path:path.resolve(__dirname, "dist"),
            filename: "bundle.js"
        }
    
6.  清除原先的dist
    const CleanWebpackPlugin = require('clean-webpack-plugin');
    new CleanWebpackPlugin(['dist'])

7.  配置package.json
    "build": "webpack --progress --config webpack_config_prod.js"

优化打包:
    
    抽离第三方包

    1.  抽离图片
        {
            test: /\.(png|jpg|gif)$/,
            use: [
                {
                    loader: 'url-loader',
                    options: {
                        limit: 4000,//大于4kb就抽离出去
                        name:"images/[name]-[hash:5].[ext]"
                    }
                }
            ]
        }

    2.  明确第三方库
        https://doc.webpack-china.org/plugins/commons-chunk-plugin/

        entry: {
            quanjiatong:['react','react-dom','react-router-dom'],
            fetchJsonp:['fetch-jsonp'],
            bundle:'./src/main.js' 
        }
        output: {
            path:path.resolve(__dirname, "dist"),
            filename: "js/[name].js"
        }
        new webpack.optimize.CommonsChunkPlugin({
                name: ['quanjiatong','fetchJsonp'],
                minChunks: Infinity,
        })

    3.  抽离对三方样式
        https://github.com/webpack-contrib/extract-text-webpack-plugin

        yarn add extract-text-webpack-plugin --dev

        //抽离第三方样式的包
        const ExtractTextPlugin = require("extract-text-webpack-plugin");
                    
        {
            test: /\.css$/,
            use: ExtractTextPlugin.extract({
              fallback: "style-loader",
              use: [
                    {
                        loader: 'css-loader',
                        options: {
                            minimize: true //压缩css
                        }
                    }
                ]
            })
          }
        
        new ExtractTextPlugin("styles.css"),

服务器反向代理

之后补充
相关文章
相关标签/搜索