美文网首页
React免费视频教程-入门和组件

React免费视频教程-入门和组件

作者: 吕阳 | 来源:发表于2018-01-28 16:29 被阅读125次

    第03节:初识JSX语法

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <!-- <link rel="stylesheet" href="css/style.css"> -->
        <script src="./common/react.js"></script>
        <script src="./common/react-dom.js"></script>
        <script src="http://cdn.bootcss.com/babel-core/5.8.38/browser.min.js"></script>
    </head>
    <body>
        <div id="reactContainer"></div>
            <script type="text/babel">
            var HelloComponent = React.createClass({
                render: function () {
                    return <h1>Hello World</h1>;
                }
            });
            ReactDOM.render(
                <HelloComponent/>,
                document.getElementById('reactContainer')
            );
        </script>
    </body>
    </html>
    

    使用了jsx.

    <body>
        <div id="reactContainer"></div>
           <script>
            var HelloComponent = React.createClass({
                render:function(){
                    return React.createElement('h1',null,'Hello world');
                }
            });
            ReactDOM.render(
                React.createElement(HelloComponent,null),
                document.getElementById('reactContainer')
                );
        </script>
    </body>
    

    通过上边的代码你可以发现JSX的好处。

    • 可以使用熟悉的语法仿照HTML来定义虚拟DOM。
    • 程序代码更加直观。
    • 于JavaScript之间等价转换,代码更加直观。
    JSX中的表达式

    JSX是支持表达式的,你只要使用{}括号,就可以使用表达式了。我们把HelloWorld程序改写成使用表达式的。

    我们把上边的程序改写成带表达式的形式。

    var HelloComponent =React.createClass({
        render:function(){
            return <h1>Hello {this.props.name?this.props.name:'world'}</h1>;
        }
    });
     
    ReactDOM.render(
        <HelloComponent name="jspang"/>,
        document.getElementById('reactContainer')
    )
    

    第04节:进阶JSX语法

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <!-- <link rel="stylesheet" href="css/style.css"> -->
        <script src="./common/react.js"></script>
        <script src="./common/react-dom.js"></script>
        <script src="http://cdn.bootcss.com/babel-core/5.8.38/browser.min.js"></script>
    </head>
    
    <body>
        <div id="reactContainer"></div>
        <script type="text/babel">
            let names = ['LOUIS VUITTON','hermes','Tiffany & Co']
            var HelloComponent = React.createClass({
                render: function () {
                    return <div>
                    {
                        names.map(function (name) {
                            return <div key={name}>Hello,{name}</div>
                        })
                    }
                    </div>
                }
            }); 
            ReactDOM.render(
                <HelloComponent/>,
                document.getElementById('reactContainer')
            );
        </script>
    </body>
    </html>
    

    上边的代码,我们使用了ES6的语法maps来进行进行循环,循环时需要注意的是,新版本的React需要使用key,如果没有key虽然会出来效果,但是控制台会包错。key的作用是生成虚拟DOM时,需要使用key来进行标记,DOM更新时进行比较。

    • 数组中的JSX

    我们上边的例子是循环数组的内容到JSX中,其实在数组中可以直接使用JSX语法,看下面的例子。

    <body>
        <div id="reactContainer"></div>
        <script type="text/babel">
            let arr = [
                <h1 key='1'>LOUIS VUITTON</h1>,
                <h1 key='2'>hermes</h1>,
                <h1 key='3'>TiffanyCo</h1>
                ];
            
            ReactDOM.render(
                <div>{arr}</div>,
                document.getElementById('reactContainer')
            );
        </script>
    </body>
    
    

    SX允许直接在模版插入JavaScript变量。如果这个变量是一个数组,则会展开这个数组的所有成员。

    总结:通过两节课的我们对JSX有了初步认识,虽然React可以不使用任何其他插件,但是JSX的好处太多,React也鼓励使用,在实际工作中也是百分百使用的,所以以后的课程中我们都会使用JSX。

    第05节:React组件:state成员

    • react_demo05.html
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
        <!-- <link rel="stylesheet" href="css/style.css"> -->
        <script src="./common/react.js"></script>
        <script src="./common/react-dom.js"></script>
        <script src="http://cdn.bootcss.com/babel-core/5.8.38/browser.min.js"></script>
    </head>
    
    <body>
        <div id="reactContainer"></div>
    
        <script type="text/babel">
                var  TextBoxComponent = React.createClass({
                    getInitialState:function(){
                        return {enable:false}
                    },
                    handleClick:function(event){
                        this.setState({enable:!this.state.enable})
                    },
                    render:function(){
                        return (
                            <p>
                                <input type="text" disabled={this.state.enable} />
                                <button onClick={this.handleClick}>改变textbox状态</button>
                            </p>
                        )
                    }
                });
        
                ReactDOM.render(<TextBoxComponent/>,document.getElementById("reactContainer"));
            </script>
    
    
    </body>
    
    </html>
    
    • state成员

    组件总是需要和用户互动的。React的一大创新,就是将界面组件看成一个状态机,用户界面拥有不同状态并根据状态进行渲染输出,用户界面和数据始终保持一致。开发者的主要工作就是定义state,并根据不同的state渲染对应的用户界面。

    • setState()

    通知React组件数据发生变化的方法是调用成员函数setState(data,callback)。这个函数会合并data到this.state,并重新渲染组件。渲染完成后,调用可选的callback回调。(大部分情况下不需要调用回调,因为React会负责把界面更新到最新状态)

    • 动手敲个小例子

    我们用一个小例子来了解一下状态机的机制。该例子包含一个文本框和一个按钮,单击按钮可以改变文本框的编辑状态:禁止编辑或允许编辑。

    程序中需要注意的点

    1. getInitialState函数必须有返回值,可以是null,false,一个对象。
    2. 访问state数据的方法是”this.state.属性名”。
    3. 变量用{}包裹,不需要再加双引号。
    05state.gif

    第06节:React组件:props和render成员

    props是组件固有属性的集合,其数据由外部传入,一般在整个组件的生命周期中都是只读的。属性的初识值通常由React.createElement函数或者JSX中标签的属性值进行传递,并合并到组件实例对象的this.props中。

    • props实例

    这里一点点写一个真实的props程序,并让大家更加了解如何定义props。

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>React-props</title>
        <script src="./common/react.js"></script>
        <script src="./common/react-dom.js"></script>
        <script src="http://cdn.bootcss.com/babel-core/5.8.38/browser.min.js"></script>
    </head>
    
    <body>
        <div id="demo"></div>
        <script type="text/babel">
            let HelloBox=React.createClass({
                render:function(){
                    return <div>{'Hello '+this.props.myattr}</div>;
                }
            })
            ReactDOM.render(<HelloBox myattr="world"/>,document.getElementById("demo"));
        </script>
    </body>
    
    </html>
    

    我们不应该修改props中的值。事实上,如果要在组件外更改也是一个很麻烦的事,需要找到组件实例,这没有必要。在设计组件时,就要想好组件哪些使用state,哪些使用props集合,那些使用state集合。通常固定的组件内只读的、应由父组件传递进来的属性适合放在props集合中,如组件的类名、颜色、字体、事件响应回调函数等。

    • props与state的区别

    props不能被其所在的组件修改,从父组件传递进来的属性不会在组件内部更改;state只能在所在组件内部更改,或在外部调用setState函数对状态进行间接修改。

    • render成员函数

    首先说render是一个函数,它对于组件来说,render成员函数是必需的。render函数的主要流程是检测this.props和this.state,再返回一个单一组件实例。

    render函数应该是纯粹的,也就是说,在render函数内不应该修改组件state,不读写DOM信息,也不与浏览器交互。如果需要交互,应该在生命周期中进行交互。


    微信截图_20180128141927.png

    第07节:React组件:生命周期

    一个组件完整的生命周期包含实例化阶段、活动阶段、销毁阶段三个阶段。每个阶段又由相应的方法管理。

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>React-props</title>
        <script src="./common/react.js"></script>
        <script src="./common/react-dom.js"></script>
        <script src="http://cdn.bootcss.com/babel-core/5.8.38/browser.min.js"></script>
    </head>
    <body>
        <div id="demo"></div>
        <script type="text/babel">
           var AddCount=React.createClass({
               getInitialState:function(){
                   console.log('1...getInitialSate');
                   return {count:1};
               },
               componentWillMount:function(){
                console.log('2...componentWillMount');
               },
               componentDidMount:function(){
                   console.log('3...componentDidMount');
               },
               componentWillUpdate:function(){
                   console.log('4...componentWillUpdate');
               },
               componentDidUpdate:function(){
                   console.log('4...componentDidUpdate');
               },
               handleClick:function(event){
                   this.setState({count:this.state.count+1})
               },
     
               render:function(){
                   return(
                       <p>
                        {this.state.count}<br/>
                        <button onClick={this.handleClick}>Add</button>
                       </p>
                   )
               }
           })
            ReactDOM.render(
               <AddCount/>,
                document.getElementById("demo")
           );
        </script>
    </body>
    </html>
    

    过程中涉及三个主要的动作术语:

    • mounting:表示正在挂接虚拟DOM到真实DOM。
    • updating:表示正在被重新渲染。
    • unmounting:表示正在将虚拟DOM移除真实DOM。

    每个动作术语提供两个函数:

    • componentWillMount()
    • componentDidMount()
    • componentWillUpdate(object nextProps, object nextState)
    • componentDidUpdate(object prevProps, object prevState)
    • componentWillUnmount()

    实例编写

    通过一个简单的实例,来看React组件的生命周期。
    这个案例在每个生命周期里都加入了输出语句,我们可以打开控制台看代码的执行过程。


    07生命周期.gif

    第08节:React组件小实例-必做练习

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>生命周期案例</title>
        <script src="./common/react.js"></script>
        <script src="./common/react-dom.js"></script>
        <script src="http://cdn.bootcss.com/babel-core/5.8.38/browser.min.js"></script>
    </head>
    
    <body>
        <div id="demo"></div>
        <script type="text/babel">
          var Hello = React.createClass({
              getInitialState:function(){
                  return {
                      opacity:1.0
                  }
              },
              componentDidMount: function () {
                setInterval(function () {
                    var opacity = this.state.opacity;
                    opacity -= .05;
                    if (opacity < 0.1) {
                        opacity = 1.0;
                    }
                    this.setState({
                        opacity: opacity
                    });
                    }.bind(this), 100);
              },
              render:function(){
                  return (
                      <div style={{opacity:this.state.opacity}}>
                           <h2>Hello {this.props.name}</h2> 
                      </div>
                  )
              }
          });
          ReactDOM.render(
              <Hello name="world"/>,
              document.getElementById('demo')
          )
        </script>
    </body>
    
    </html>
    

    第09节:React组件:this.props.children

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>React-props</title>
        <script src="./common/react.js"></script>
        <script src="./common/react-dom.js"></script>
        <script src="http://cdn.bootcss.com/babel-core/5.8.38/browser.min.js"></script>
    </head>
    
    <body>
        <div id="demo"></div>
        <script type="text/babel">
            var NotesList=React.createClass({ render:function(){ return(
            <ol>
                { React.Children.map(this.props.children,function(child){ return(
                <li>{child}</li>) }) }
            </ol>
            ) } }); ReactDOM.render(
            <NotesList>
                <span>hello</span>
                <span>world</span>
            </NotesList>, document.getElementById("demo") );
     
        </script>
    </body>
    
    </html>
    

    上面代码的NoteList组件有两个span子节点,他们都可以通过this.props.children读取。这里需要注意,this.props.children的值有三种可能,如果当前组件没有子节点,他就是undfined;如果有一个子节点,数据类型是object;如果有多个子节点,数据类型就是array。所以处理this.proprs.children的时候要小心。

    第10节:React组件:props属性验证

    组件的属性是可以接收任何值的,但有时候我们希望对外界父级组件传递进来的属性数据进行限定,比如希望name属性不能缺少、onClick属性必须是函数类型等,这对确保组件被正确使用非常有意义。为此React引入了propTypes机制。React.PropTypes提供各种验证器(validator)来验证传入数据的有效性。当向props传入无效数据时,React会在JavaScript控制台抛出警告。

    • PropsTypes

    我们来作一个小列子,看一下PropTypes的用法。

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>React-props</title>
        <script src="./common/react.js"></script>
        <script src="./common/react-dom.js"></script>
        <script src="http://cdn.bootcss.com/babel-core/5.8.38/browser.min.js"></script>
    </head>
    
    <body>
        <div id="demo"></div>
        <script type="text/babel">
           var MyTitle = React.createClass({
               propTypes:{
                    title:React.PropTypes.string.isRequired,
               },
    
               render:function(){
                   return <h2>{this.props.title}</h2>
               }
           })
           var data=123;
           ReactDOM.render(<MyTitle title={data}/>,document.getElementById('demo'));
    
        </script>
    </body>
    
    </html>
    

    第11节:React组件:获取真实DOM节点

    React中的DOM也是虚拟DOM(virtual DOM),这点跟我们以前讲的Vue非常类似。只有当它插入文档以后,才会变成真实的DOM。React也是在虚拟DOM发生变化时,进行比对后,只渲染变化的部分,它是React极高性能的主要原因之一。

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>React-props</title>
        <script src="./common/react.js"></script>
        <script src="./common/react-dom.js"></script>
        <script src="http://cdn.bootcss.com/babel-core/5.8.38/browser.min.js"></script>
    </head>
    
    <body>
        <div id="demo"></div>
        <script type="text/babel">
           var MyTitle = React.createClass({
               propTypes:{
                    title:React.PropTypes.string.isRequired,
               },
    
               render:function(){
                   return <h2>{this.props.title}</h2>
               }
           })
           var data=123;
           ReactDOM.render(<MyTitle title={data}/>,document.getElementById('demo'));
    
        </script>
    </body>
    
    </html>
    

    这个案例很简单,就是有一个文本框,当你点击按钮时,光标定位到文本框里。这时就必须获取真实的DOM节点,虚拟DOM是拿不到用户输入的。为了做到这一点,文本框必须有一个ref属性,用this.refs.xxx就可以返回真实的DOM节点。

    • 注意:

    由于this.refs.[refName]属性获取的是真实DOM,所以必须得到虚拟DOM插入文档以后,才能使用这个属性,否则会报错。

    相关文章

      网友评论

          本文标题:React免费视频教程-入门和组件

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