react + webpack笔记

date: 2017.01.22; modification:2018.05.17

目录:

1 环境安装

npm i -g yarn
yarn add --dev webpack@2.1.0-beta.22 react react-dom
yarn add --dev babel-core babel-loader@7.1.1 babel-preset-es2015 babel-preset-react babel-preset-stage-1 babel-preset-stage-3
yarn add --dev babel-plugin-transform-runtime # 这里是为了增加对async/await的支持.

2 代码目录

|-- dist
|   |-- bundle.js
|   `-- index.html
|-- src
|   |-- components
|   |   `-- Component.jsx
|   `-- main.js
`-- webpack.config.js

index.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>ReactDemo</title>
    </head>
    <body>
        <!--要插入React组件的位置-->
        <div id="content"></div>
        <!--引入bundle.js-->
        <script src="bundle.js"></script>
    </body>
</html>

main.js:

import React from 'react';
import ReactDom from 'react-dom';
import Component1 from './components/Component.jsx';

ReactDom.render(
    <Component1 />,
    document.getElementById('content')
);

src/components/Component.jsx:

import React from 'react';

class Component1 extends React.Component {
    render() {
        return (
            <div>Hello World!</div>
        )
    }
}

//导出组件
export default Component1;

说明:

webpack.config.js:


    module.exports = {
        entry: __dirname + "/src/main.js",  // 唯一入口文件
        output: {                           // 输出目录
            path: __dirname + "/dist",      // 打包后的js文件存放的地方
            filename: "bundle.js"           // 打包后输出的js的文件名
        },

        module: {
            loaders: [ //loaders加载器
                {
                    test: /\.(js|jsx)$/,    // 一个匹配loaders所处理的文件的拓展名的正则表达式, 这里用来匹配js和jsx文件(必须)
                    exclude: /node_modules/,// 屏蔽不需要处理的文件(文件夹)(可选)
                    loader: 'babel',        // loader的名称(必须)
                    query: {
                        presets: ['es2015', 'react'],
                        plugins: ["transform-runtime", "babel-plugin-transform-regenerator", "babel-plugin-transform-es2015-modules-commonjs"]  // 对async/await的支持.
                    }
                }
            ]
        }
    };

3 样式

分类:

HTML与react样式设置区别:

内联样式:

如:

<p style={{backgroundColor:"yellow", borderWidth:2, borderStyle:"solid"}}>test</p>

对象样式:

同内联样式.

选择器样式:

html中:
<head>
    <style>
        .pStyle {
            font-size:30px;
        }
    </style>
</head>

jsx中:
    <p className="pStyle">test pStyle by class</p>

4 props

class TestProps extends React.Component {
    render() {
        return (
            <p>{this.props.myP1}</p>
        );
    }
}

ReactDom.render(<TestProps myP1="paragraph 1"/>, app);

全部属性:

...props

5 props.children

所有的子节点, 如:

class MyList extends React.Component {
    render() {
        return (
            <div>
                <ul>
                {
                    React.Children.map(this.props.children, function(item) {
                        return <li>{item}</li>;
                    })
                }
                </ul>
            </div>
        );
    }
}

ReactDom.render(
    <MyList>
        <p>item 1</p>
        <p>item 2</p>
        <p>item 3</p>
    </MyList>
, app);

6 默认值

class MyComponent extends React.Component {
    render() {
        return (
            <div>
                <p>{this.props.mycontent}</p>
            </div>
        );
    }
}
MyComponent.defaultProps = {
    mycontent: "Default content."
}

ReactDom.render(
    <MyComponent />,
    app
);

将显示: Default content.

7 state

class MyComponent extends React.Component {
    constructor(props){
        super(props);
        this.state = { checked: false };
        this.onInputChange = this.onInputChange.bind(this); // 没有这句则下面的回调会找不到this.
    }

    onInputChange () {
        this.setState({ checked: !this.state.checked });
    }

    render() {
        var text = this.state.checked ? "Checked" : "Unchecked";
        return (
            <div>
                <input type="checkbox" onChange={this.onInputChange} />
                {text}
            </div>
        );
    }
}

8 生命周期

class MyComponent extends React.Component {
    constructor(props){
        super(props);
    }

    componentWillMount() {
        console.log("componentWillMount()");
    }

    componentDidMount() {
        console.log("componentDidMount()");
    }

    componentWillReceiveProps(nextProps) {
        console.log("componentWillReceiveProps()");
    }

    shouldComponentUpdate(nextProps, nextState) {
        console.log("shouldComponentUpdate()");
        return true;
    }

    componentWillUpdate(nextProps, nextState) {
        console.log("componentWillUpdate()");
    }

    componentDidUpdate(nextProps, nextState) {
        console.log("componentDidUpdate()");
    }

    componentWillUnmount(nextProps, nextState) {
        console.log("componentWillUnmount()");
    }

    render() {
        console.log("render()");
        return (
            <div>
            </div>
        );
    }
}

ReactDom.render(<MyComponent />, app);
ReactDom.render(<MyComponent />, app);
ReactDom.unmountComponentAtNode(document.getElementById("content"));

运行结果:

第一次ReactDom.render()后:

componentWillMount()
render()
componentDidMount()

第二次ReactDom.render()后:

componentWillReceiveProps()
shouldComponentUpdate()
componentWillUpdate()
render()
componentDidUpdate()

ReactDom.unmountComponentAtNode后:

componentWillUnmount()

9 参考资料

使用async/await的说明: https://segmentfault.com/a/1190000009673642