美文网首页
19-React 快速学习与使用

19-React 快速学习与使用

作者: magic_pill | 来源:发表于2018-03-22 00:11 被阅读18次

一、React 相关概念:

1.1. 含义:
  • React 是一个用于构建用户界面的JavaScript库。
  • React主要用于构建UI,很人多认为 React 是 MVC 中的 V(视图)。
  • React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站,并于 2013 年 5 月开源。
  • React 拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它。
1.2. 作用:
  • 用做UI: 许多人把React当做MVC设计模式中的视图(view),当把React成为你的技术掌握之后, 它可以很轻松应用于一个小功能的项目。
  • 虚拟DOM:React用一个”虚拟DOM”实现了超高的性能,配合nodeJS也可以实现在服务端的渲染,不存在耗时的浏览器dom渲染。
  • 数据流: React是一种减少引用数据流的实现方式,并且比传统的方式更容易实现数据绑定。
  • React Native 项目就是使用 React 和 JavaScript 创建本机 APP。
1.3. 特点:
  • 声明式设计 −React采用声明范式,可以轻松描述应用。
  • 高效 −React通过对DOM的模拟,最大限度地减少与DOM的交互。
  • 灵活 −React可以与已知的库或框架很好地配合。
  • JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。
  • 组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
  • 单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。

二、安装

  • 关于安装这里不再赘述,你可以在官网 http://facebook.github.io/react/ 下载最新版;
  • 也可以直接使用 cdn 上的React CDN 库,地址如下:
<script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
说明:
1.react.min.js - React 的核心库;
2.react-dom.min.js - 提供与 DOM 相关的功能;
3.browser.min.js - 用于将 JSX 语法转为 JavaScript 语法,关于 JSX 语法在下面说明。

三、 React JSX 语法说明

  • JSX 的语法如下:
ReactDOM.render(
    <h1>Hello, world!</h1>,
    document.getElementById('example')
);
以上代码将一个 h1 标题,插入 id="example" 节点中。
如果我们需要使用 JSX,则 <script> 标签的 type 属性需要设置为 text/babel。
我们可以在 JSX 中使用 JavaScript 表达式。表达式写在花括号 {} 中
  • 完整示例:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
    <script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
</head>
<body>
    <div id="em1"></div>
    <script type="text/babel">
        ReactDOM.render(
            <h1>Hello, YijiangWang! {1+2}</h1>,
            document.getElementById('em1')
        )
    </script>
</body>
</html>

四、 组件

  • 通过方法 React.createClass 方法用于生成一个组件类;
  • 如果我们需要向组件传递参数,可以使用 this.props 对象,实例如下:
var Yjw_component = React.createClass({
  render: function() {
    return <h1>Hello {this.props.name}</h1>;
  }
});

ReactDOM.render(
  <Yjw_component name="Yjw" />,
  document.getElementById('example')
);
注意:
  1.原生 HTML 元素名以小写字母开头,而自定义的 React 类名以大写字母开头;
  2.组件类只能包含一个顶层标签,否则也会报错。
  • 复合组件:
//自定义符合组件
/**
*   注意点:
 *   1、组件首字母要大写
 *   2、不能 return 多个控件,如果需要返回多个控件,可以在最外层用一个控件进行包装
 *   3、return 控件时,要用 () 进行包装
* */
var Contenttxt = React.createClass({
    render:function () {
        return (
                <h1>{this.props.contentt}</h1>
        )
    }
});
var Titletxt = React.createClass({
    render:function () {
        return (
                <h2>{this.props.titlet}</h2>
        )
    }
});

var Article = React.createClass({
    render:function () {
        return (
            <div>
                <Titletxt titlet={this.props.titlet} />
                <Contenttxt contentt={this.props.contentt} />
            </div>
        )
    }
});

ReactDOM.render(
    <Article titlet="I'm the title" contentt="I'm the content"></Article>,
        document.getElementById("example")
)

五、React State(状态)

//自定义一个组件
var Yjw = React.createClass({
    //定义初始状态
    getInitialState:function () {
        return {like:true};
    },
    //定义一个点击事件
    handle:function () {
        this.setState({like:!this.state.like})
    },
    render:function () {
        var text = this.state.like?"喜欢":"不喜欢";
        return (
                <h1 onClick={this.handle}>{this.props.titlet}如果你 <ins>{text}</ins> 我,就点我</h1>
        )
    },
});

//渲染一个组件
ReactDOM.render(
        <Yjw/>,
        document.getElementById("example")
)

六、React Props

  • 设置默认 props
var Dprop = React.createClass({
    getDefaultProps:function () {
        return {
            name:"yijiang"
        }
    },

    render:function () {
        return (
                <h1>这里是默认的:{this.props.name}</h1>
        )
    }
});
ReactDOM.render(
        <Dprop name="mage"/>,
        document.getElementById("prop1")
);
  • props 和 state 结合使用
var Name = React.createClass({
    render:function () {
        return <h1>I'm {this.props.name}</h1>
    }
});

var Site = React.createClass({
    render:function () {
        return <a href={this.props.site}>{this.props.site}</a>
    }
});

var Website = React.createClass({
    getInitialState:function () {
        return {
            name:"yijiang",
            site:"www.baidu.com"
        }
    },

    clickName:function () {
        this.setState({name:"magege"});
    },

    render:function () {
        return (
                <div onClick={this.clickName}>
                    <Name name={this.state.name}/>
                    <Site site={this.state.site}/>
                </div>
        )
    }
});

ReactDOM.render(
        <Website/>,
        document.getElementById("prop2")
);
  • prop 验证:这里验证 title 必须为 string 类型,并且是必须字段:
var Vprop = React.createClass({
    propTypes:{
        title:React.PropTypes.string.isRequired
    },

    render:function () {
        return (<h1>{this.props.title}</h1>)
    }
});

ReactDOM.render(
        <Vprop title="123"/>,
        document.getElementById("prop3")
)
更多的验证器说明如下
React.createClass({
  propTypes: {
    // 可以声明 prop 为指定的 JS 基本数据类型,默认情况,这些数据是可选的
   optionalArray: React.PropTypes.array,
    optionalBool: React.PropTypes.bool,
    optionalFunc: React.PropTypes.func,
    optionalNumber: React.PropTypes.number,
    optionalObject: React.PropTypes.object,
    optionalString: React.PropTypes.string,

    // 可以被渲染的对象 numbers, strings, elements 或 array
    optionalNode: React.PropTypes.node,

    //  React 元素
    optionalElement: React.PropTypes.element,

    // 用 JS 的 instanceof 操作符声明 prop 为类的实例。
    optionalMessage: React.PropTypes.instanceOf(Message),

    // 用 enum 来限制 prop 只接受指定的值。
    optionalEnum: React.PropTypes.oneOf(['News', 'Photos']),

    // 可以是多个对象类型中的一个
    optionalUnion: React.PropTypes.oneOfType([
      React.PropTypes.string,
      React.PropTypes.number,
      React.PropTypes.instanceOf(Message)
    ]),

    // 指定类型组成的数组
    optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),

    // 指定类型的属性构成的对象
    optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),

    // 特定 shape 参数的对象
    optionalObjectWithShape: React.PropTypes.shape({
      color: React.PropTypes.string,
      fontSize: React.PropTypes.number
    }),

    // 任意类型加上 `isRequired` 来使 prop 不可空。
    requiredFunc: React.PropTypes.func.isRequired,

    // 不可空的任意类型
    requiredAny: React.PropTypes.any.isRequired,

    // 自定义验证器。如果验证失败需要返回一个 Error 对象。不要直接使用 `console.warn` 或抛异常,因为这样 `oneOfType` 会失效。
    customProp: function(props, propName, componentName) {
      if (!/matchme/.test(props[propName])) {
        return new Error('Validation failed!');
      }
    }
  },
  /* ... */
});

六、React 组件 API

  • 设置状态:setState

  • 替换状态:replaceState

  • 设置属性setProps

  • 替换属性replaceProps

  • 强制更新:forceUpdate

  • 获取DOM节点:findDOMNode

  • 判断组件挂载状态:isMounted

    这里列举两例:setState 和 setProps,其它 API 使用大同小异,这里不一一例举:
    
//setState
var Sta = React.createClass({
    getInitialState:function () {
        return {
            clickCount:0
        }
    },

//            clickEvent:function () {
//                this.setState({clickCount:this.state.clickCount+1})
//            },
//这里两个 clickEvent 方法作用相同
    clickEvent:function () {
        this.setState(function (state) {
            return {clickCount:state.clickCount+1}
        })
    },

    render:function () {
        return <h1 onClick={this.clickEvent}>点击的次数为:{this.state.clickCount}</h1>
    }

});

ReactDOM.render(
        <Sta/>,
        document.getElementById("example1")
);

//setProps
var Sprop = React.createClass({
    getInitialProps:function () {
        return {
            clickCount:0
        }
    },

    clickEvent:function () {
        this.setProps({clickCount:this.props.clickCount+1})
    },
//这里两个 clickEvent 方法作用相同
//            clickEvent:function () {
//                this.setProps(function (state) {
//                    return {clickCount:state.clickCount+1}
//                })
//            },

    render:function () {
        return <h1 onClick={this.clickEvent}>点击的次数为:{this.props.clickCount}</h1>
    }

});

ReactDOM.render(
        <Sta/>,
        document.getElementById("example2")
)

七、生命周期函数

  • 生命周期的方法有:
    • componentWillMount 在渲染前调用,在客户端也在服务端。
    • componentDidMount : 在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异部操作阻塞UI)。
    • componentWillReceiveProps 在组件接收到一个新的prop时被调用。这个方法在初始化render时不会被调用。
    • shouldComponentUpdate 返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。 可以在你确认不需要更新组件时使用。
    • componentWillUpdate在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。
    • componentDidUpdate 在组件完成更新后立即调用。在初始化时不会被调用。
    • componentWillUnmount在组件从 DOM 中移除的时候立刻被调用。
<body>
    <div id="em1"></div>
    <div id="em2"></div>

    <script type="text/babel">
        //定义一个 Hello 组件,并且每秒钟重新渲染一次
        var Hello = React.createClass({
            //初始化 state
            getInitialState:function () {
                return {opacity:1.0}
            },

            componentDidMount:function () {
                this.timer = setInterval(function () {
                    var opacity = this.state.opacity;
                    opacity -= 0.2;
                    if (opacity < 0.1){
                        opacity = 1.0;
                    }
                    this.setState({opacity:opacity})
                }.bind(this),1000);
            },

            render:function () {
                return (
                        <div style={{opacity:this.state.opacity}}>
                            Hello {this.props.name}
                        </div>
                )
            }
        });

        ReactDOM.render(
                <Hello name="Yijiang"/>,
                document.getElementById("em1")
        );

        //定义一个 Button 组件
        var Button = React.createClass({
            getInitialState:function () {
                return {data:0}
            },
            setNewNumber:function () {
                this.setState({data:this.state.data+1})
            },
            render:function () {
                return (
                        <div>
                            <button onClick={this.setNewNumber}>Increment</button>
                            <Content myNumber={this.state.data}></Content>
                        </div>
                )
            }
        });

        //定义一个 Content 组件
        var Content = React.createClass({
            componentWillMount:function () {
                console.log("component Will Mount");
            },
            componentDidMount:function () {
                console.log("component Did Mount");
            },
            componentWillReceiveProps:function(newProps) {
                console.log('Component WILL RECIEVE PROPS!')
            },
            shouldComponentUpdate:function(newProps, newState) {
                return true;
            },
            componentWillUpdate:function(nextProps, nextState) {
                console.log('Component WILL UPDATE!');
            },
            componentDidUpdate:function(prevProps, prevState) {
                console.log('Component DID UPDATE!')
            },
            componentWillUnmount:function() {
                console.log('Component WILL UNMOUNT!')
            },

            render: function () {
                return (
                        <div>
                            <h3>{this.props.myNumber}</h3>
                        </div>
                );
            }
        });
        ReactDOM.render(
                <div>
                    <Button />
                </div>,
                document.getElementById('em2')
        );

        /**
         * 首先会展示前两条:
         * component Will Mount
         * component Did Mount
         * 当点击之后会显示以下三条
         * Component WILL RECIEVE PROPS!
         * Component WILL UPDATE!
         * Component DID UPDATE!
         */
    </script>
</body>

八、React AJAX:

  • React 组件的数据可以通过 componentDidMount 方法中的 Ajax 来获取,当从服务端获取数据库可以将数据存储在 state 中,再用 this.setState 方法重新渲染 UI。
  • 当使用异步加载数据时,在组件卸载前,在 componentWillUnmount 里面取消未完成的请求。
var UserGist = React.createClass({
    getInitialState: function() {
        return {
            username: '',
            lastGistUrl: ''
        };
    },

    componentDidMount: function() {
        this.serverRequest = $.get(this.props.source, function (result) {
            var lastGist = result[0];
            this.setState({
                username: lastGist.owner.login,
                lastGistUrl: lastGist.html_url
            });
        }.bind(this));
    },

    componentWillUnmount: function() {
        this.serverRequest.abort();
    },

    render: function() {
        return (
                <div>
                    {this.state.username} 用户最新的 Gist 共享地址:
                    <a href={this.state.lastGistUrl}>{this.state.lastGistUrl}</a>
                </div>
        );
    }
});

ReactDOM.render(
        <UserGist source="https://api.github.com/users/octocat/gists" />,
        document.getElementById("em1")
);

九、React 表单与事件:

<body>
    <div id="em1"></div>
    <div id="em2"></div>
    <div id="em3"></div>
    <div id="em4"></div>
    <script type="text/babel">
        //一、React 表单与事件
        //设置输入框 input 值value = {this.state.data}。在输入框值发生变化时我们可以更新 state。
        var Yjw_input = React.createClass({
            getInitialState:function () {
                return {value:"Yijiangwang"}
            },
            changeValue:function (event) {
                this.setState({value:event.target.value})
            },
            render:function () {
                var txt = this.state.value;
                return (
                        <div>
                            <h3>这里是value的值:{this.state.value}</h3>
                            <input value={this.state.value} onChange={this.changeValue}/>
                        </div>
                )
            }
        });

        ReactDOM.render(
                <Yjw_input></Yjw_input>,
                document.getElementById("em1")
        );

        //在子组件上使用表单。 onChange 方法将触发 state 的更新并将更新的值传递到子组件的输入框的 value 上来重新渲染界面。
        //在父组件通过创建事件句柄 (handleChange) ,并作为 prop (updateStateProp,这里名字可以随意取) 传递到你的子组件上。
        //创建一个子组件
        var Content = React.createClass({
            render:function () {
                return  <div>
                    <h4>{this.props.myDataProp}</h4>
                    <input type="text" value={this.props.myDataProp} onChange={this.props.updateStateProp} />
                </div>;
            }
        });
        //创建一个父组件
        var HelloMessage = React.createClass({
            getInitialState: function() {
                return {value: 'Hello Yijiang!'};
            },
            handleChange: function(event) {
                this.setState({value: event.target.value});
            },
            render: function() {
                var value = this.state.value;
                return <div>
                    <Content myDataProp = {value}
                             updateStateProp = {this.handleChange}></Content>
                </div>;
            }
        });
        ReactDOM.render(
                <HelloMessage />,
                document.getElementById('em2')
        );

        //二、React 事件
        //通过 onClick 事件来修改数据
        var Yjw_click = React.createClass({
            getInitialState: function() {
                return {value: 'Hello Yijiang!'};
            },
            handleChange: function(event) {
                this.setState({value: 'Hello YijiangWang!'})
            },
            render: function() {
                var value = this.state.value;
                return <div>
                    <button onClick={this.handleChange}>点我</button>
                    <h4>{value}</h4>
                </div>;
            }
        });
        ReactDOM.render(
                <Yjw_click />,
                document.getElementById('em3')
        );

        //当需要从子组件中更新父组件的 state 时,需要在父组件通过创建事件句柄 (handleChange) ,并作为 prop (updateStateProp) 传递到子组件上。
        //子组件
        var Child_event = React.createClass({
            render: function() {
                return  <div>
                    <button onClick = {this.props.updateStateProp}>点我</button>
                    <h4>{this.props.myDataProp}</h4>
                </div>
            }
        });
        //父组件
        var Father_event = React.createClass({
            getInitialState: function() {
                return {value: 'Hello Yijiang!'};
            },
            handleChange: function(event) {
                this.setState({value: 'Hello YijiangWang!'})
            },
            render: function() {
                var value = this.state.value;
                return <div>
                    <Child_event myDataProp = {value}
                             updateStateProp = {this.handleChange}></Child_event>
                </div>;
            }
        });
        ReactDOM.render(
                <Father_event />,
                document.getElementById('em4')
        );
    </script>
</body>

十、React Refs

  • React 支持一种非常特殊的属性 Ref ,你可以用来绑定到 render() 输出的任何组件上。
  • 这个特殊的属性允许你引用 render() 返回的相应的支撑实例( backing instance )。这样就可以确保在任何时间总是拿到正确的实例。
  • 使用方法:
//绑定一个 ref 属性到 render 的返回值上:
<input ref="myInput" />
//在其它代码中,通过 this.refs 获取支撑实例:
var input = this.refs.myInput;
var inputValue = input.value;
var inputRect = input.getBoundingClientRect();
  • 具体实例:
<div id="em1"></div>
<script type="text/babel">
    //可以通过使用 this 来获取当前 React 组件,或使用 ref 来获取组件的引用
    var Yjw_component = React.createClass({
                handleClick: function() {
                    // 使用原生的 DOM API 获取焦点
                    this.refs.myInput.focus();
                },
                render: function() {
                    //  当组件插入到 DOM 后,ref 属性添加一个组件的引用于到 this.refs
                    return (
                            <div>
                                <input type="text" ref="myInput" />
                                <input
                                        type="button"
                                        value="点我输入框获取焦点"
                                        onClick={this.handleClick}
                                />
                            </div>
                    );
                }
            });

    ReactDOM.render(
            <Yjw_component />,
            document.getElementById('em1')
    );
</script>

相关文章

网友评论

      本文标题:19-React 快速学习与使用

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