React.js

作者: 旧丶时候 | 来源:发表于2017-04-03 16:46 被阅读256次

    0. 前言

    “任时光匆匆流去,我只在乎你”,最近这些时间都没怎么更新文章,希望大家不要见怪啊,哈哈!最近公司在做react.js项目,然而我不是太熟,也是一个小白,也正在学习当中,然而大家如果有什么好的学习文档也可以留给我,谢谢大家了。

    u=2186464112,3083010432&fm=23&gp=0.jpg

    1. 简介

    React 是一个用于构建用户界面的 JAVASCRIPT 库。

    2.特点

    1. 声明式设计 −React采用声明范式,可以轻松描述应用。
    2. 高效 −React通过对DOM的模拟,最大限度地减少与DOM的交互。
    3. 灵活 −React可以与已知的库或框架很好地配合。
    4. JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。
    5. 组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
    6. 单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单。

    3. 要点

    在说代码的前提下,我想说几点比较重要的几点:

    1. 需要引入几个文件,顺序不能改变


      Paste_Image.png
    2. 组件式开发,什么都是组件,里面有什么创建组件,props传值啊,绑定事件啊等
    3. 插件,最重要的就是recat-router,路由

    4. 代码实现

    1.在title下面先引入几个文件

    <script src="../bower_components/react/react.min.js"></script>
    <script src="../bower_components/react/react-dom.min.js"></script>
    <script src="../lib/browser.min.js"></script>
    
    2.代码
    • script type 的类型 babel
    • 包含节点只能一个
    • 组件一定要有闭合
    • 可以用es6语法也可以用es5语法
    3. HTML里面有个容器
     <div id="demo"></div>
    
    4. js代码
     <script type="text/babel">
            class Hello extends  React.Component{
                getDate(){
                    return new Date-0;
                }
                render(){
                    var name = this.getDate();
                    return (
                        <div>
                            <div>123</div>
                            <div>hello,{this.getDate()}</div>
                            <input type="text"/>
                        </div>
                    )
                }
            }
    
            ReactDOM.render(
                    <Hello/>,
                    document.getElementById('demo')
            )
        </script>
    

    除了那些我们写好的原生的HTML div 标签,react里面我们可以自定义标签,它呢代表并不是一个真实的DOM节点,在react看来,它只是react Components的实例而已,那这些react Components是怎么呈现在页面中的呢,就是调用react里面render()这个方法,第一个参数是我们要渲染的react Components,第二个参数Components渲染完之后要插入的位置的容器element,综上所述也就是将hello这个渲染结果插入到ID为demo的element容器里。

    那么我们看一下渲染结果


    Paste_Image.png

    那么在看一下咱们渲染之后的页面结构

    Paste_Image.png

    那么现在看是不是已经把我说的全部都体现了出来,还有那个为data-recatroot的div,咱们好像没有命名这个属性,这个是recat内部给你做的事情,因为我也是初学者,不太明白,当然你知道了,可以告诉我。

    还有添加一些样式都怎么添加,还可以这样添加。

    5. HTML结构代码

    对,你猜对了,还是这个结构代码,一个简单的容器

     <div id="demo"></div>
    
    6. CSS代码

    在这里我设置的是我在react 那个render()方法里的一个className的div,为什么叫className,因为class是js里的保留字,所以我们得用className这个属性,而且我们这样写也是设置样式的一种方式。

     <style type="text/css">
            .demo{
                font-size: 50px;
            }
        </style>
    
    7. js代码

    下面你要注意我写的render()方法里的东西,还有另外一种设置样式的方式,那就是设置内联样式,为什么不直接设置fontSize:50,backgroundColor:'red',color:'#fff'”?因为recat这里不支持是字符串的形式,要写一个对象,key和value这样的方式,它才可以解析。

    <script type="text/babel">
            class Hello extends  React.Component{
    
                render(){
                    var name = "刘玉森";
                    var style={fontSize:50,backgroundColor:'red',color:'#fff'};
    
                    return (
                        <div>
                            <div className="demo">123</div>
                            <div style={style}>hello,{name}</div>
                            <input type="text"/>
                        </div>
                    )
                }
            }
    
            ReactDOM.render(
                    <Hello/>,
                    document.getElementById('demo')
            )
        </script>
    

    展示出来之后的结果


    Paste_Image.png

    props在react中是很重要的一个方法


    Paste_Image.png
    8. HTML容器

    这里呢容器没有变,还是那个容器

    <div id="demo"></div>
    
    9. js代码
    <script type="text/babel">
        class Hello extends  React.Component{
    
            render(){
                return (
                    <div>
                        <div>123</div>
                        <div>hello,{this.props.name}</div>
                    </div>
                )
            }
        }
        class Hello1 extends  React.Component{
    
            render(){
                return (
                    <div>
                        <div>123</div>
                        <div>hello,{this.props.address}</div>
                    </div>
                )
            }
        }
    
        class Parent extends  React.Component{
            render(){
                return (
                    <div>
                        <Hello name={this.props.name}/>
                        <Hello1 address={this.props.address}/>
                    </div>
                )
            }
        }
    
        ReactDOM.render(
                <Parent name="刘玉森"  address="110"/>,
                document.getElementById('demo')
        )
    </script>
    

    这里呢我就得大家说一下我的那个代码,首先呢,我先自定义了一个parent这个标签,然后我创建了一个parent这个组件,我利用this.props把组件外向组件内传值,然后我再创建俩个hello,hello1的组件,获取父元素parent里的值。

    看一下页面渲染之后的效果


    Paste_Image.png

    再看一下页面渲染之后的页面结构


    Paste_Image.png
    10.HTML代码

    依然还是这个容器

    <div id="demo"></div>
    
    11. js代码
    <script type="text/babel" >
        class Hello extends  React.Component{
    
            render(){
                return (
                    <ul>
                        <li>00000000</li>
                        {
                            this.props.children.map(function(item){
                                return <li>{item}</li>;
                            })
                        }
                    </ul>
                )
            }
        }
    
    
        ReactDOM.render(
            <Hello>
            <div>11111111</div>
            <div>22222222</div>
            <div>33333333</div>
            <div>44444444</div>
            </Hello>,
            document.getElementById('demo')
        )
    </script>
    

    这里呢,我们先写一个li跟我们循环遍历出来的li做个鲜明的对比,这里就利用this.props.children这个方法来读取组件内部的子标签,可以该数组进行遍历

    那么我们看下渲染之后的结果


    Paste_Image.png

    还有我们渲染之后的页面结构


    Paste_Image.png
    12. HTML代码

    容器......

     <div id="demo"></div>
    
    13. js文件

    先写一个我遇到的坑

    <script type="text/babel" >
        class Hello extends  React.Component{
            getDefaultProps(){
                return {
                    name : "刘玉森"
                };
            }
            render(){
                return (
                    <h1> hello,{this.props.name}</h1>
                )
            }
        }
        
        ReactDOM.render(
            <Hello/>,
            document.getElementById('demo')
        )
    </script>
    

    这样定义组件你会发现,它不显示,因为使用 Component 定义的组件不能这样去设置默认值

    看一下显示的结果


    Paste_Image.png

    是吧,它不显示,我也是醉了!!!

    下面就演示一下正确的写法,下面是见证奇迹的时刻了!

    <script type="text/babel" >
        class Hello extends  React.Component{
    
            render(){
                return (
                    <h1> hello,{this.props.name}</h1>
                )
            }
        }
        
        Hello.defaultProps = {
            name : "刘玉森"
        }
        
        ReactDOM.render(
            <Hello/>,
            document.getElementById('demo')
        )
    </script>
    

    实践是检验真理的唯一标准,来啊互相伤害啊!看图说话


    Paste_Image.png

    厉害了,我的哥!就想问还有谁,低调啊,这也是我试出来的,慢慢摸索来的...

    14. HTML文件

    容器还是容器

    <div id="demo"></div>
    

    在recat里面我们添加一些事件怎么做到呢?

    15. js文件
     <script type="text/babel">
            class Hello extends  React.Component{
                clkFunc(){
                    alert('Hello');
                }
                render(){
    
                    return (
                        <div>
                            <button onClick={this.clkFunc.bind(this)}>点我</button>
                        </div>
                    )
                }
            }
            ReactDOM.render(
                    <Hello />,
                    document.getElementById('demo')
            )
        </script>
    

    bind这个方法,它是es5里的方法,可以改变this的指向,详细请你自己查询一下,我解释的不是太好。

    那么看一下渲染页面之后的结果


    GIF.gif

    ref标签的属性,可以从组件中获取真实的DOM节点,也可以绑定事件


    Paste_Image.png
    16. HTML代码

    容器...

    <div id="demo"></div>
    
    17. js代码
    <script type="text/babel">
            class Hello extends  React.Component{
                clkFunc(){
                    this.refs.iptText.value = "hello,刘玉森";
                }
                render(){
    
                    return (
                        <div>
                            <input ref="iptText" />
                            <button onClick={this.clkFunc.bind(this)}>点我</button>
                        </div>
                    )
                }
            }
    
    
            ReactDOM.render(
                    <Hello />,
                    document.getElementById('demo')
            )
        </script>
    

    看一下渲染之后的结果


    GIF.gif

    通过ref这个标签的属性来绑定标签,在添加一个点击事件,调用clkFunc这个函数执行里面的语句,然后把值传入input框内,渲染页面。

    下面说一下react的生命周期,在创建到销毁的生命周期,状态和属性在生命周期中是如何流转的?那么首先要了解react在浏览器中存在的三个状态,分别是mounted、update、unmounted,代表的含义是安装(实例化)、更新(存在期)、销毁(清理)。


    timg.jpg
    • mouted 是指react components被render这个方法解析生成对应的DOM节点并插入浏览器的DOM结构的一个过程。
    • update 是指一个mounted的recat components被重新的render的过程
    • unmounted 是指一个mounted的react components对应的DOM节点被从DOM结构中移除的这样一个过程
    • 每一个状态recat都封装了对应的hook函数,翻译成中文就是“钩子函数”,WINDOW的消息处理机制为了能在应用程序中监控系统的各种事件消息,提供了挂接各种反调函数(HOOK)的功能。

    如果让我们自己封装这样的hook函数,怎么设计封装?相信大多是人都i知道will和did,将要怎么怎么样和已经怎么怎么样,将要mounted、update、unmounted,和已经mounted、update、unmounted,事实上react的设计思想也是如此,只不过人家比我们想的更加全面一些,更详细一些,那么来一张图片吧


    timg.jpg
    18. HTML代码

    上容器

    <div id="demo"></div>
    
    19. js代码
     <script type="text/babel">
            class Hello extends React.Component{
                constructor(props){
                    super(props);
                    this.state = {
                        opacity:0.1
                    }
                }
                componentDidMount(){
                    this.timer = setInterval(function(){
                        var opacity = this.state.opacity;
                        opacity -=0.05;
                        if(opacity<0.1){
                            opacity=1
                        }
                        this.setState({
                            opacity:opacity
                        })
    
                    }.bind(this),100)
                }
                render(){
                    return (
                            <div style={{opacity:this.state.opacity,fontSize:50}}>
                                这个是测试react的生命周期
                            </div>
                    )
                }
            }
    
            ReactDOM.render(
                    <Hello/>,
                    document.getElementById('demo')
            )
        </script>
    

    这里我们可以调用两个函数,componentWillMount和componentDidMount的两个方法,这两个函数的区别是componentWillMount在mounting前被调用,componentDidMount在mounted后被调用,然后测试一下react的生命周期

    看一下渲染之后的页面效果是什么样的


    GIF.gif

    刚才的代码中我有用到state这个方法,这个解释就是说,react把组件看成状态机getInitialState,设置默认值,setState()可以修改state的值,每次state的值发生改变的时候,都会重新渲染UI


    Paste_Image.png
    20. HTML代码

    这是这个文件的最后一个容器...

    <div id="demo"></div>
    
    21. js文件
     <script type="text/babel">
            class Hello extends  React.Component{
                constructor(props){
                    super(props);
                    this.state = {
                        name:'刘玉森',
                        address:'北京',
                    }
                }
                clkFunc(){
    
                    this.setState({
                        name:'liuyusen',
                        address:'BeJing'
                    })
    
                }
                render(){
    
                    return (
                        <div>
                            <div>hello,{this.state.name},{this.state.address}!!!</div>
                            <button onClick={this.clkFunc.bind(this)}>点我</button>
                        </div>
                    )
                }
            }
    
    
    
            ReactDOM.render(
                    <Hello />,
                    document.getElementById('demo')
            )
        </script>
    

    这里我有一个点击按钮,当我点击按钮的时候,改变state的值,props和state差别,props一般情况下我们通过组建调用方,在调用组件的时候指定的,props一旦指定了在一般情况下是不会改变的,而state是私属于当前组件的,state的值是可变的,正所谓“props是专情的,state是花心的”,怎么样修改state的值呢?那么就要用到setState这个方法来修改state的值。

    看一下刚才的代码渲染之后的页面效果


    GIF.gif

    5. 结束语

    我知道我写的文章可能不是太好,可能存在许多的问题,当然也需要大家的指点,最后希望我写的文章能给大家带来帮助!!!

    相关文章

      网友评论

      • e04882ed7412:不是父子组件的两个组件之间怎么通信呢?
        e04882ed7412:@Mr_森哥 谢谢你:+1::+1::+1:
        旧丶时候:@Mr_森哥 回答你之前的问题,在GitHub上引用来的,见谅,
        react推崇的是单向数据流,自上而下进行数据的传递,但是由下而上或者不在一条数据流上的组件之间的通信就会变的复杂。解决通信问题的方法很多,如果只是父子级关系,父级可以将一个回调函数当作属性传递给子级,子级可以直接调用函数从而和父级通信。

        组件层级嵌套到比较深,可以使用上下文getChildContext来传递信息,这样在不需要将函数一层层往下传,任何一层的子级都可以通过this.context直接访问。

        兄弟关系的组件之间无法直接通信,它们只能利用同一层的上级作为中转站。而如果兄弟组件都是最高层的组件,为了能够让它们进行通信,必须在它们外层再套一层组件,这个外层的组件起着保存数据,传递信息的作用,这其实就是redux所做的事情。

        组件之间的信息还可以通过全局事件来传递。不同页面可以通过参数传递数据,下个页面可以用location.param来获取。其实react本身很简单,难的在于如何优雅高效的实现组件之间数据的交流。
        旧丶时候: @UidExist @UidE太难了。。。我也刚学
      • Victor细节:名字写错啦😄
        旧丶时候: @Victor细节 😂😂

      本文标题:React.js

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