React入门

环境配置:

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

React入门_第1张图片
01.png

简单使用
React入门_第2张图片
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 

这是{text}按钮

} } ReactDOM.render(,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 

这是{text}按钮

} })

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


03.gif
props -- 属性

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

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

var Text = React.createClass({

    render : function () {
        return 

{this.props.name}

} }) ReactDOM.render(,document.getElementById("mydiv"));

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

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

    render() {
        return 
hello {this.props.text}
} } //父组件 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
} }) ReactDOM.render(,document.getElementById("mydiv"));
4.gif

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

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

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

来个表单提交的例子:

var ChildGenderSelect = React.createClass({

    render:function () {

        return 
    }
})

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 
} }) ReactDOM.render(,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方法中添加的所有任务都需要在该方法中撤销,比如创建的定时器或添加的事件监听器。

你可能感兴趣的:(React入门)