React入门

环境配置:

首先根据官网的教程,建立一个简单的工程需要引入三个文件:react.js、react-dom.js、babel.min.js。其中bable.min.js可以是教程中的链接,也可以是自己下载的文件直接拷贝进去,然后直接使用即可,这里需要申明js的类型为text/babel。

01.png

简单使用
2.png

可以看到,我们使用一个组件首先继承React.Componet,声明方法render(){},render方法顾名思义是用来渲染组件,render直接返回一个html标签,标签里面就是我们要展现的页面内容,这里使用的JSX的语法,如果编辑器不支持JSX语法,需要在设置->Languages->JavaScript中切换。
另外有一点是,这里的组件可以分装嵌套使用,就像java/Android中的组件继承、嵌套是一个概念,非常接近java的语法了,这就是组件化,最大的好处是实现组件的重用。
最后需要把组件绘制到页面中,ReactDOM.render(),把需要渲染的组件和需要渲染的位置传入其中,最后在页面中展示出来。
这里的DOM是react的虚拟DOM,里面的节点既可以包含标签,又可以包含自定义的组件,区别在于html标签小写开头,自定义的大写开头,可以实现快平台。

state--状态

一般来说,你需要在constructor中初始化state

React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。
React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。
不需要直接操作DOM,而是通过修改state,自动更新界面
示例:

lass Text extends React.Component {

    //设置初始状态的值
    getInitialState() {
        return {isLike:false}
    }

    //响应点击事件
    handleClick() {
        //改变状态
        this.setState({isLike:!this.state.isLike});
    }

    render() {
        var text = this.state.isLike?"确定":"取消"
        return <p onClick={this.handleClick}>
            这是{text}按钮
        </p>
    }
}

ReactDOM.render(<Text/>,document.getElementById("mydiv"));
/*Uncaught TypeError: Cannot read property 'isLike' of null*/

这里代码说明:

  • 在React中的属性命名遵循小驼峰命名法,不然无法识别,如果上面的onClick
  • 通过响应点击事件,调用this.setState()方法给组件的state属性赋值,改变state的值,从而react自动重新调用的render方法重新渲染
  • 给state赋值之前需要在组件的生命周期getInitialState()方法给state进行初始化工作,getInitialState在组件创建的时候回调用。
    然而这样运行会报错(这里需要安装react的官方chorme的插件):
    Uncaught TypeError: Cannot read property 'isLike' of null

这里说isLike为空?说明getInitialState方法没有被调用,其实这里还涉及到另外一个知识:
react创建组件有两种方式,第一种就像上述代码直接继承,第二种是调用React.creatClass()方法,第二种方式才能走生命周期的方法,将代码改为:

var Text = React.createClass( {

    //设置初始状态的值
    getInitialState:function() {
        return {isLike:false}
    },

    //响应点击事件
    handleClick:function() {
        //改变状态
        this.setState({isLike:!this.state.isLike});
    },

    render:function() {
        var text = this.state.isLike?"确定":"取消"
        return <p onClick={this.handleClick}>
            这是{text}按钮
        </p>
    }
})

如果需要用继承的方式个state赋值,需要在构造函数里面,如果是原生的js代码需要操作DOM:$('#id').innerText = "";这样子就不能跨平台了。


03.gif
props -- 属性

props是在父组件中指定,而且一经指定,在被指定的组件的生命周期中则不再改变。 对于需要改变的数据,我们需要使用state

state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。这就是为什么有些容器组件需要定义 state 来更新和修改数据。 而子组件只能通过 props 来传递数据。
首先看下案例:

var Text = React.createClass({

    render : function () {
        return <p>{this.props.name}</p>
    }

})

ReactDOM.render(<Text name="I Love You"/>,document.getElementById("mydiv"));

通过在引用的时候在组件的标签内命名key:value值,这样传入的值就是赋值给这个组件的默认属性,通过this.props.key来使用,这个属性和java的构造穿参类似。
那怎么理解子组件只能通过props来传递数据呢?试想这样一个场景:父组件包裹子组件,当父组件内容改变的时候子组件跟着要改变,这就需要通过props给子组件串值。
案例:

//子组件
class TextComponet extends React.Component {

    render() {
        return <div>hello {this.props.text}</div>
    }
}

//父组件
var WrapperComponent = React.createClass({

    getInitialState:function () {
      return {text:""}
    },

    //e是Event对象,target是目标对象,value是值。
    handleChange: function (e) {
        // alert(e.target.value);
        this.setState({text:e.target.value});
    },
    
    render:function () {
        return <div>
            <TextComponet text={this.state.text}/>
            <input type="text" onChange={this.handleChange}/>
        </div>
    }
})

ReactDOM.render(<WrapperComponent name="I Love You"/>,document.getElementById("mydiv"));

4.gif

上面案例经历了的步骤:
1、给父组件状态赋初始值
2、输入框变化——>修改父组件的state
3、state变化重新渲染调用render(),子组件也会重新渲染,把父组件的state值作为子组件的props值传递给子组件。
4、子组件的内容改变。

这个方法可以当做一个模板套路来是用。

那么子组件发生变化怎么通知父组件呢?

来个表单提交的例子:

var ChildGenderSelect = React.createClass({

    render:function () {

        return <select onChange={this.props.handleSelectChange}>
            <option value="1">男</option>
            <option value="0">女</option>
        </select>
    }
})

var ParentForm = React.createClass({

    getInitialState:function () {
        return {gender:0}
    },

    handleChange: function (e) {
        this.setState({gender:e.target.value})
        //ajax发起请求
    },

    handlSubmit:function (e) {
        //屏蔽表单的默认行为
        e.preventDefault()

        var request = new XMLHttpRequest();
        request.open("GET","text.json?gender=" + this.state.gender);
        request.onreadystatechange = handler;
        request.setRequestHeader("Accept","application/json");
        request.responseType="json";
        request.send();

        function handler() {
            if (this.status === 200) {
                console.log("ok");
            }
        }
    },

    render: function () {

        return <form onSubmit={this.handlSubmit}>
            <ChildGenderSelect handleSelectChange={this.handleChange}/>
            <button type="submit">提交</button>
        </form>
    }
})
ReactDOM.render(<ParentForm/>,document.getElementById("mydiv"));

解析:父组件传递给子组件的props一个父组件的方法handleChange(),当子组件的选择器发生改变的时候通过调用this.props.handleSelectChange(),最终调用父组件的handleChage(),和java的观察者模式思想有点像。

小结:父组件通知子组件变化通过改变父组件的状态,把父组件的状态值当做子组件的props传递进去,当父组件的state发生改变的时候重新调用render方法,从而达到传值的目的,而子组件通知父组件,通过传递父组件方法给子组件的props,当子组件发生改变的时候回调这个方法,和java的观察者很像。

React的生命周期

1.getDefaultProps
作用于组件类,只调用一次,返回对象用于设置默认的props,对于引用值,会在实例中共享。

2.getInitialState
作用于组件的实例,在实例创建时调用一次,用于初始化每个实例的state,此时可以访问this.props。

3.componentWillMount
在完成首次渲染之前调用,此时仍可以修改组件的state。

4.render
必选的方法,创建虚拟DOM,该方法具有特殊的规则:

  • 只能通过this.props和this.state访问数据
  • 可以返回null、false或任何React组件
  • 只能出现一个顶级组件(不能返回数组)
  • 不能改变组件的状态
  • 不能修改DOM的输出

5.componentDidMount
真实的DOM被渲染出来后调用,在该方法中可通过this.getDOMNode()访问到真实的DOM元素。此时已可以使用其他类库来操作这个DOM。
在服务端中,该方法不会被调用。

6.componentWillReceiveProps
组件接收到新的props时调用,并将其作为参数nextProps使用,此时可以更改组件props及state。

    componentWillReceiveProps: function(nextProps) {
        if (nextProps.bool) {
            this.setState({
                bool: true
            });
        }
    }

7.shouldComponentUpdate
组件是否应当渲染新的props或state,返回false表示跳过后续的生命周期方法,通常不需要使用以避免出现bug。在出现应用的瓶颈时,可通过该方法进行适当的优化。
在首次渲染期间或者调用了forceUpdate方法后,该方法不会被调用

8.componentWillUpdate
接收到新的props或者state后,进行渲染之前调用,此时不允许更新props或state。

9.componentDidUpdate
完成渲染新的props或者state后调用,此时可以访问到新的DOM元素。

10.componentWillUnmount
组件被移除之前被调用,可以用于做一些清理工作,在componentDidMount方法中添加的所有任务都需要在该方法中撤销,比如创建的定时器或添加的事件监听器。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,290评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,107评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,872评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,415评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,453评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,784评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,927评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,691评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,137评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,472评论 2 326
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,622评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,289评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,887评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,741评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,316评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,490评论 2 348

推荐阅读更多精彩内容

  • 1.React 的学习资源 react官方首页https://facebook.github.io/react/ ...
    贾里阅读 2,858评论 0 0
  • 在React这股目前最热前端框架之风刮来之前,一直在Cocos2d-html5游戏和半路出家的Android应用的...
    hahafei阅读 363评论 0 2
  • React简介 React是一个用于构建用户界面的JavaScript库,主要有以下几个特点: 声明式设计--Re...
    紫诺_qiu阅读 892评论 0 2
  • 欢迎访问我的博客 早期,我们开发web应用,只能是通过请求服务器,服务端响应请求,返回一个页面,,每次浏览器都得对...
    惊鸿三世阅读 516评论 0 2
  • 1.SSH 安全外壳协议.Secure Shell.由 IETF 的网络小组(Network Working Gr...
    廖马儿阅读 2,329评论 0 0