react基本介绍

2017-02-06  本文已影响0人  overisover

关于react,sublime的常用插件
地址:http://www.cnblogs.com/erniu/p/5784319.html

数组的两个方法

//过滤
var arr=[1,2,3,4];
arr.filter(function(item){return item===1})
//[1] 返回,满足条件的新数组;
//遍历
var arr=comments.map(function(item,i){
            return (
                <li key={i} >//这里必须加个key 值,为了方便react查找,并无其他作用
                        <p className="userName">{item.userName}说:</p>
                        <p className="content">{item.content}</p>
                        <span>删除</span>
                </li>
                )
            
})

React 的优点

组件模式:代码复用和团队分工
虚拟 DOM:性能优势
移动端支持:跨终端

使用react的基本结构

<!DOCTYPE html>
<html>
  <head>
//导入文件使用
    <script src="../build/react.js"></script>
    <script src="../build/react-dom.js"></script>
    <script src="../build/browser.min.js"></script>
  </head>
  <body>
    <div id="example"></div>
    <script type="text/babel">
      // ** Our code goes here! **
    </script>
  </body>
</html>

上面代码有两个地方需要注意。首先,最后一个 <script> 标签的 type 属性为 text/babel 。这是因为 React 独有的 JSX 语法,跟 JavaScript 不兼容。凡是使用 JSX 的地方,都要加上 type="text/babel" 。

其次,上面代码一共用了三个库: react.js 、react-dom.js 和 Browser.js ,它们必须首先加载。其中,react.js 是 React 的核心库,react-dom.js 是提供与 DOM 相关的功能,Browser.js 的作用是将 JSX 语法转为 JavaScript 语法,这一步很消耗时间,实际上线的时候,应该将它放到服务器完成。

ReactDOM.render()

ReactDOM.render 是 React 的最基本方法,用于将模板转为 HTML 语言,并插入指定的 DOM 节点。

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('example')
);

JSX 语法

  1. 遇到'{', 看成js
  2. {变量}, 直接解析
  3. {arr}, 数组则展开里面所有的项
    React 使用 JSX 语法,JavaScript 代码中可以写 HTML 代码.
    let myTitle = <h1>Hello, world!</h1>;
    JSX 语法解释
    (1)JSX 语法的最外层,只能有一个节点。
// 错误
let myTitle = <p>Hello</p><p>World</p>;

HTML 语言直接写在 JavaScript 语言之中,不加任何引号,这就是 [JSX 的语法]它允许 HTML 与 JavaScript 的混写

var names = ['Alice', 'Emily', 'Kate'];

ReactDOM.render(
  <div>
  {
    names.map(function (name) {
    //name指数组里的每一个值;
    //map是遍历数组的方法;
      return <div>Hello, {name}!</div>
    })
  }
  </div>,
  document.getElementById('example')
);

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

var arr = [
  <h1>Hello world!</h1>,
  <h2>React is awesome</h2>,
];
ReactDOM.render(
  <div>{arr}</div>,
  document.getElementById('example')
);

组件

React.createClass 方法就用于生成一个组件类,
1,组件类只能包含一个顶层标签,
2,组件类的第一个字母必须大写,
3,jsx语法中,class是关键字,需要写成className,才能设置样式


var HelloMessage = React.createClass({
  render: function() {
    return <h1>Hello {this.props.name}</h1>;
  }
});

ReactDOM.render(
  <HelloMessage name="John" />,
  document.getElementById('example')
);

上面代码中,变量 HelloMessage 就是一个组件类。模板插入 <HelloMessage /> 时,会自动生成 HelloMessage 的一个实例(下文的"组件"都指组件类的实例)。所有组件类都必须有自己的 render 方法,用于输出组件。
注意,组件类的第一个字母必须大写,否则会报错,比如HelloMessage不能写成helloMessage。另外,组件类只能包含一个顶层标签,否则也会报错。
添加组件属性,有一个地方需要注意,就是 class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字

this.props.children

它表示组件的所有子节点

PropTypes 就是用来验证组件实例的属性是否符合要求

var MyTitle = React.createClass({
  propTypes: {
    title: React.PropTypes.string.isRequired,
  },

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

  ReactDOM.render(
        <MyTitle title='aaa' />,
        document.getElementById('example')
      );

上面的Mytitle组件有一个title属性。PropTypes 告诉 React,这个 title 属性是必须的,而且它的值必须是字符串。
getDefaultProps 方法可以用来设置组件属性的默认值。

var MyTitle = React.createClass({
  getDefaultProps : function () {
    return {
      title : 'Hello World'
    };
  },

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

ReactDOM.render(
  <MyTitle />,
  document.body
);

获取真实的DOM节点

组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。根据 React 的设计,所有的 DOM 变动,都先在虚拟 DOM 上发生,然后再将实际发生变动的部分,反映在真实 DOM上,这种算法叫做 DOM diff ,它可以极大提高网页的性能表现。
但是,有时需要从组件获取真实 DOM 的节点,这时就要用到 ref
属性

<div id="container"></div>
<script src="src/react.js"></script>
<script src="src/react-dom.js"></script>
<!-- 解析jsx语法 -->
<script src="src/browser.min.js"></script>  

<script type="text/babel">
var container = document.getElementById('container');

//refenrence  引用
var MyComponent = React.createClass({
  handleClick: function() {
    //真实的DOM元素
    var oTextInput = this.refs.myTextInput;
    var button = this.refs.button;
    button.style.background = 'blue';
    oTextInput.focus();
    oTextInput.style.background = 'red';
  },
  render: function() {

    return (
      <div>
        <input type="text" ref="myTextInput" />
        <input ref="button" type="button" value="Focus the text input" onClick={this.handleClick} />
      </div>
    );
  }
});

ReactDOM.render(
  <MyComponent />,
  container
);

</script>

上面代码中,组件 MyComponent 的子节点有一个文本输入框,用于获取用户的输入。这时就必须获取真实的 DOM 节点,虚拟 DOM 是拿不到用户输入的。为了做到这一点,文本输入框必须有一个 ref 属性,然后 this.refs.[refName] 就会返回这个真实的 DOM 节点。
需要注意的是,由于 this.refs.[refName] 属性获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个属性,否则会报错。上面代码中,通过为组件指定 Click 事件的回调函数,确保了只有等到真实 DOM 发生 Click 事件之后,才会读取 this.refs.[refName] 属性。
React 组件支持很多事件,除了 Click 事件以外,还有 KeyDown 、Copy、Scroll 等

this.state

组件免不了要与用户互动,React 的一大创新,就是将组件看成是一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染 UI

<div class="box"></div>
<script type="text/babel">
            var Hello=React.createClass({
                    getInitialState:function(){//获取初始状态
                        return {
                            liked:true
                        }
                    },  
                    handle:function(){
                        var liked=!this.state.liked;
                        //点击时,状态切换
                        this.setState({
                            liked:liked
                        })
                    },
                    render:function(){
                        //状态改变时,文本改变,
                        var text='like';
                        if(!this.state.liked){
                            text='don\'t like';
                        }
                        return <div onClick={this.handle}>
                            you {text} it,点击切换
                        </div>
                    }
            })
            ReactDOM.render(
                <Hello></Hello>,
                document.querySelector('.box')
            )
    </script>

input 通过改变状态,来获取input输入的值

<script type="text/babel">
            var Input=React.createClass({
                getInitialState:function(){
                    return {
                        text:'hello!'//设置input初始状态,
                    }
                },
                changeHandle:function(ev){
                    var value=ev.target.value;

                    this.setState({
                        text:value//改变状态,为输入的值
                    })
                    
                },
                render:function(){
                    var text=this.state.text//获取状态
                    return (<div>
                            <input value={text} onChange={this.changeHandle}/>
                            <p>{text}</p>
                        </div>)
                }

            })
            ReactDOM.render(
                <Input></Input>,
                document.querySelector('.box')
            )
    </script>

上面代码是一个 LikeButton 组件,它的 getInitialState 方法用于定义初始状态,也就是一个对象,这个对象可以通过 this.state 属性读取。当用户点击组件,导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件。
由于 this.props 和 this.state 都用于描述组件的特性,可能会产生混淆。一个简单的区分方法是,this.props 表示那些一旦定义,就不再改变的特性,而 this.state 是会随着用户互动而产生变化的特性。

通过state改变,来实时获取input输入的值

用户在表单填入的内容,属于用户跟组件的互动,所以不能用 this.props 读取

<div id="example"></div>
    <script type="text/babel">
      var Input = React.createClass({
        getInitialState: function() {
          return {value: 'Hello!'};
        },
        handleChange: function(event) {
          this.setState({value: event.target.value});
        },
        render: function () {
          var value = this.state.value;
          return (
            <div>
              <input type="text" value={value} onChange={this.handleChange} />
              <p>{value}</p>
            </div>
          );
        }
      });

      ReactDOM.render(<Input/>, document.getElementById('example'));
    </script>

上面代码中,文本输入框的值,不能用 this.props.value 读取,而要定义一个 onChange 事件的回调函数,通过 event.target.value 读取用户输入的值。textarea 元素、select元素、radio元素都属于这种情况,

react 练习实例

pubsub(发布者-订阅者模式)

学生信息列表,包括筛选,删除

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="css/bootstrap.css">
    <script src="src/react.js"></script>
    <script src="src/react-dom.js"></script>
    <script src="src/browser.min.js"></script>
    <!-- pub publish 发布
    sub subscribe 订阅 -->
    <script src="src/pubsub.js"></script>
</head>
<body>
    <div class="student"></div>
    <script type="text/babel">
        var data=[
            {name:"student1",gender:"女",age:18,height:165,weigth:45,_id:2},
            {name:"student2",gender:"男",age:35,height:180,weigth:80,_id:0},
            {name:"student3",gender:"女",age:22,height:171,weigth:60,_id:6},
            {name:"student4",gender:"男",age:26,height:175,weigth:70,_id:1},
            {name:"student2",gender:"女",age:18,height:170,weigth:50,_id:3},
            {name:"student4",gender:"女",age:38,height:166,weigth:50,_id:4},
            {name:"student3",gender:"男",age:30,height:175,weigth:65,_id:5}
        ];
        var StudentItem=React.createClass({
            deleteItem:function(){
                var _id=this.props.item._id;
                //触发deleteItem事件
                PubSub.publish('deleteItem',_id)//发布事件
            },
            render:function(){
                var item=this.props.item;
                return (
                    <tr>
                        <td>{item.name}</td>
                        <td>{item.gender}</td>
                        <td>{item.age}</td>
                        <td>{item.height}</td>
                        <td>{item.weigth}</td>
                        <td><a href="javascript:;" onClick={this.deleteItem}>删除</a> </td>
                    </tr>
                )
            }
        })
        var StudentInfo=React.createClass({
            render:function(){
                var studentData=this.props.studentData;
                return (
                    <table className="table table-bordered table-hover">
                            <thead>
                                <tr>
                                    <th>姓名</th>
                                    <th>性别</th>
                                    <th>年龄</th>
                                    <th>身高(cm)</th>
                                    <th>体重(kg)</th>
                                    <th>操作</th>
                                </tr>
                            </thead>
                            <tbody id="tb">
                                {
                                    studentData.map(function(item,i){
                                        return (
                                            <StudentItem item={item}/>
                                        )
                                    })
                                }                                                          
                            </tbody>
                        </table>
                )
            }
        })
        var StudentApp=React.createClass({
            getInitialState:function(){
                return {
                    studentData:this.props.studentData,
                    gender:'all',
                    name:''
                }
            },
            genderFilterHandle:function(ev){//选择不同性别,改变状态为相应的状态
                this.setState({
                    gender:ev.target.value
                })
            },
            nameFilterHandle:function(ev){//选择学生名字,改变状态为相应的状态
                this.setState({
                    name:ev.target.value
                })
            },
            //在真实的dom插入进文档时触发
            componentDidMount:function(){
                var self=this;//因为下面函数的this指向会改变,所以这里保存this;
                //相当于监听事件发生,如果发生点击事件,则触发该事件,删除对应的项目;
            //订阅事件
                PubSub.subscribe('deleteItem',function(evName,_id){
                    var studentData=self.state.studentData;
                    studentData=studentData.filter(function(item){
                        return item._id!==_id;
                    });
                    //更新状态和刷新页面,
                    self.setState({
                        studentData:studentData
                    })
                })
            },
            render:function(){
                var studentData=this.state.studentData;
                var gender=this.state.gender;
                var name=this.state.name;
                if(gender!=='all'){//判断性别
                    studentData=studentData.filter(function(item){
                        return item.gender===gender;//返回满足条件的数组
                    })
                }
                if(name!==''){//判断 名字是否为空
                    studentData=studentData.filter(function(item){
                        if(item.name.indexOf(name)!=-1){//数组包含输入的值,则返回相应数组;
                            return item;//返回满足条件的数组;
                        }
                        
                    })
                }
                return (
                    <div className="container">
                    <h1>学员成信息表</h1>
                    <div className="bs-example">
                        <div className="form-group">
                            <label>按性别筛选</label>
                            <select className="form-control" onChange={this.genderFilterHandle}>
                                <option value="all">all</option>
                                <option value="男">男</option>
                                <option value="女">女</option>
                            </select>
                        </div>
                        <div className="form-group">
                            <label>按名字筛选</label>
                            <input type="text" className="form-control" placeholder="请输入名字" onChange={this.nameFilterHandle} />
                        </div>
                    </div>
                    <div className="table-responsive">
                        <StudentInfo studentData={studentData}/>
                    </div>
                </div>
                )
            }
        })
        ReactDOM.render(
        <StudentApp studentData={data} />,
        document.querySelector('.student')
        )
    </script>
</body>
</html>
上一篇下一篇

猜你喜欢

热点阅读