Ela's Notes
So Be It


Hitokoto ·
[JavaScript][React学习笔记][1]React初体验
Elatis   React, 学习笔记, JavaScript   537 | 文章字数: 9561 字

本篇将介绍一些react的基本语法

react简介

react是一个用于构建图形用户界面的JavaScript库,它的代码逻辑简单,性能高效,是一个易于学习且值得学习的库.

react特点

1.声明式设计 −React采用声明范式,可以轻松描述应用。

2.高效 −React通过对DOM的模拟,最大限度地减少与DOM的交互。

3.灵活 −React可以与已知的库或框架很好地配合。

4.JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。

5.组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。

6.单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单.

react的安装

这里推荐直接引用外链

<script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>

你也可以通过以下操作来引入最新版的react(需要安装npm):
1.创建一个新的文件夹
2.在这个文件夹中打开命令窗口或git
3.输入以下指令:

npm install -g create-react-app

待安装完成后再输入

create-react-app my-app

请耐心等待安装..安装完成后你会发现当前目录下多了一个my-app文件夹
然后进入生成的my-app文件夹

cd my-app

然后你就可以通过修改/src/APP.js来编写js代码了

如果你想要预览你写的代码,就进入自动生成的my-app文件夹下打开命令行或是git,然后输入:

npm start

默认在localhost:3000下运行,如果没有自动开启浏览器,你可以在浏览器地址栏中输入上述地址来预览
预览途中你修改了你的代码并保存,然后刷新预览网页也可以预览更改后的效果

自定义React类的用法

自定义类

我们可以利用React类的creatClass方法来创建一个特殊的类,以供配合其它react库中的方法使用.
例如下面的代码就封装了一个名为HelloMessageReact子类.
它的作用是在html代码中创建一个<h1>标签,标签中的内容是Hello World!

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

render是react库中保留的一个对象名,当我们利用ReactDOM向html文件中呈递这个HelloMessage类时,它决定了实际上到底应该对html做出何种更改
自定义的React类必须要以大写字母开头
render方法中return后面可以写在不同的行,但是包含两个以上顶层标签就会报错
比如

var HelloMessage = React.createClass({
  render: function() {
    return <h1>Hello World</h1><div>emmm</div>;
  }
});

这样就会报错,而

var HelloMessage = React.createClass({
  render: function() {
    return <div>
              <h1>Hello World</h1>
              <h2>emmm</h2>
          </div>;
  }
});

这样则是合法的

实例化自定义类

在有了上面自定义了一个名为HelloMessage的类之后,我们还需要在需要的地方实例化这个类.
先看看下面的代码:

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

如果html文件中有一个id为example的双标签,那么这个标签中就会出现一个Hello World,如果没有或者这个id对应的是单标签..当然会报错啦嘿嘿嘿

刚才的代码中调用了ReactDOM类中的render方法,而<HelloMessage />则实例化了HelloMessage类,下面那句document.getElementById('example')则指定了应该在哪输出信息
<HelloMessage />写成双标签的形式也可以,如

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

也是合法的.

向自定义的类中传递参数

要向自定义的类中传递参数,可以使用this.props对象
例如把刚才的代码改成

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

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

浏览器中会输出Hello Elatis!
其中this.props就是我刚才提到的那个对象,而this.props.name则指定了传入的参数名为name
然后在下面实例化的同时传递参数name="Elatis!",并调用到生成的<h1>标签中,所以标签中会出现刚才传入的参数
上面那部分的带html完整代码如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>React自定义类</title>
    <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
    <script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
  </head>
  <body>
    <div id="example"></div>
    <script type="text/babel">
      var HelloMessage = React.createClass({
        render: function() {
          return <h1>Hello {this.props.name}</h1>;
        }
      });

      ReactDOM.render(
        <HelloMessage name="Elatis!" />,
        document.getElementById('example')
      );
    </script>
  </body>
</html>

注:也许有人会注意到<script type="text/babel">中的type是babel而不是传统的javascript,其实bable就是react的一个编译器,当指定类型是它,标签内的代码才会被识别成react代码,当然jsx也行,但是bable是第二代编译器.

React state(状态)

React中可以通过更新组件的状态来实现更新网页界面的状态,而不用再次与DOM交互
而组件的状态可以使用this.state对象来设置,用法和this.props对象一样
要改变状态,可以使用this.setState方法

先看看以下代码:

var LikeButton = React.createClass({
        getInitialState: function() {
          return {liked: false};
        },
        handleClick: function(event) {
          this.setState({liked: !this.state.liked});
        },
        render: function() {
          var text = this.state.liked ? '喜欢' : '不喜欢';
          return (
            <p onClick={this.handleClick}>
              你<b>{text}</b>我。点我切换状态。
            </p>
          );
        }
      });

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

其中getInitialState设置了初始状态,和render一样,可以同时设置多个状态的值,比如

getInitialState: function() {
          return {liked: false,//要注意用逗号隔开
                        emmmm: false};
        },

也是合法的.

然后我们要创建一个对象来保存改变状态值的方法,也就是上文代码中的handleClick.
由于待会我们要将这个对象绑定在即将创建的标签中的onClick事件上,而事件触发会默认传入一个event参数,所以handleClick对象保存的方法设置了一个参数,如果不需要和这个参数交互,设置不传也可以,即将event删掉,变成

handleClick: function() {
          this.setState({liked: !this.state.liked});
        },

不过为了增加程序的鲁棒性健壮性,还是不要这么做为好.
然后就可以将这个Handleclick方法绑定到onClick事件上,并实例化这个组件了.就如上文代码中的render对象中保存的方法一样.
要注意的是,不同于原生html代码中的onclick一样,react中的onClickClick是大写字母开头的.其它事件也类似.
上述的带html完整代码如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>React state应用</title>
    <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
    <script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
  </head>
  <body>
    <div id="example"></div>
    <script type="text/babel">
      var LikeButton = React.createClass({
        getInitialState: function() {
          return {liked: false};
        },
        Handleclick: function(event) {
          this.setState({liked: !this.state.liked});
        },
        render: function() {
          var text = this.state.liked ? '喜欢' : '不喜欢';
          return (
            <p onClick={this.Handleclick}>
              你<b>{text}</b>我。点我切换状态。
            </p>
          );
        }
      });

      ReactDOM.render(
        <LikeButton />,
        document.getElementById('example')
      );
    </script>
  </body>
</html>

React props

上文已经介绍了如何使用props,本节将介绍props的一些其它用法

为props设置默认值

我们可以为props设置默认值,这样实例化组件时就不用再手动指定props的值了.
这里使用的是getDefaultProps对象
参考以下代码:

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

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

和刚才提到的state一样,可以同时设置多个props的初始值,方法类似.

props检验

react中还提供了保证我们的props能正确被使用的检验方法,当props被传入无效数据时,控制台会抛出警告.
检验使用的是propTypes
如以下代码就是用propTypes来检验一个title属性是否合理

var title = "test";
// var title = 123;
var MyTitle = React.createClass({
  propTypes: {
    title: React.PropTypes.string.isRequired,
  },

  render: function() {
     return <h1> {this.props.title} </h1>;
   }
});
ReactDOM.render(
    <MyTitle title={title} />,
    document.getElementById('example')
);

title属性只能是字符串,如果不是字符串则会自动转化成字符串.
当然不使用propTypes检验也是可以的...

更多验证器如下:

React.createClass({
  propTypes: {
    // 可以声明 prop 为指定的 JS 基本数据类型,默认情况,这些数据是可选的
   optionalArray: React.PropTypes.array,
    optionalBool: React.PropTypes.bool,
    optionalFunc: React.PropTypes.func,
    optionalNumber: React.PropTypes.number,
    optionalObject: React.PropTypes.object,
    optionalString: React.PropTypes.string,

    // 可以被渲染的对象 numbers, strings, elements 或 array
    optionalNode: React.PropTypes.node,

    //  React 元素
    optionalElement: React.PropTypes.element,

    // 用 JS 的 instanceof 操作符声明 prop 为类的实例。
    optionalMessage: React.PropTypes.instanceOf(Message),

    // 用 enum 来限制 prop 只接受指定的值。
    optionalEnum: React.PropTypes.oneOf(['News', 'Photos']),

    // 可以是多个对象类型中的一个
    optionalUnion: React.PropTypes.oneOfType([
      React.PropTypes.string,
      React.PropTypes.number,
      React.PropTypes.instanceOf(Message)
    ]),

    // 指定类型组成的数组
    optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),

    // 指定类型的属性构成的对象
    optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),

    // 特定 shape 参数的对象
    optionalObjectWithShape: React.PropTypes.shape({
      color: React.PropTypes.string,
      fontSize: React.PropTypes.number
    }),

    // 任意类型加上 `isRequired` 来使 prop 不可空。
    requiredFunc: React.PropTypes.func.isRequired,

    // 不可空的任意类型
    requiredAny: React.PropTypes.any.isRequired,

    // 自定义验证器。如果验证失败需要返回一个 Error 对象。不要直接使用 `console.warn` 或抛异常,因为这样 `oneOfType` 会失效。
    customProp: function(props, propName, componentName) {
      if (!/matchme/.test(props[propName])) {
        return new Error('Validation failed!');
      }
    }
  },
  /* ... */
});

state和props

state和props的区别就在于state可以通过和用户交互来改变,而props是无法改变的.
所以props一般用来设置新标签的属性,如title,class,name,如果它们不需要改变的话.
而state的作用则更显而易见了,它就相当于一种局部变量.

结束语

到此,可以看出react的封装性和便捷性确实不错.如果换成原生js的话,创建标签不会那么方便,更改标签中的值也不会那么方便.
本篇就先写到这里,下篇将介绍一些react的高级应用.

评论

发送失败 可能是您的发言太频繁或联系方式有误

提交评论

Theme LightWhite Made by Archeb With
自豪地使用Typecho
© 2017 - 2020 elatis.cn 版权所有 ICP证: 冀ICP备18008017号-1
全站共 19.11 W 字
博客已经运行了