初识React(一)

103 阅读8分钟

初识React (一)

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

React 主要用于构建UI,很多人认为 React 是 MVC 中的 V(视图)。

React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站,并于 2013 年 5 月开源。

React 拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它。

React 特点

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

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

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

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

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

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

React 安装

可以直接使用 Staticfile CDN 的 React CDN 库

    <script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
    <script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <!-- 生产环境中不建议使用 -->
    <script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>

也可以使用官方提供的 CDN 地址

    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <!-- 生产环境中不建议使用 -->
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>

通过 npm 使用 React

    $ npm install -g cnpm --registry=https://registry.npm.taobao.org
    $ npm config set registry https://registry.npm.taobao.org

使用 create-react-app 快速构建 React 开发环境

   1.  $ cnpm install -g create-react-app
   2.  $ create-react-app my-app
   3.  $ cd my-app/
   4.  $ npm start

React 元素渲染

元素是构成 React 应用的最小单位,它用于描述屏幕上输出的内容。

    const element = <h1>Hello, world!</h1>;

与浏览器的 DOM 元素不同,React 当中的元素事实上是普通的对象,React DOM 可以确保 浏览器 DOM 的数据内容与 React 元素保持一致。

###将元素渲染到 DOM 中

首先我们在一个 HTML 页面中添加一个 id="example" 的

:

    <div id="example"></div>

在此 div 中的所有内容都将由 React DOM 来管理,所以我们将其称为 "根" DOM 节点。 我们用 React 开发应用时一般只会定义一个根节点。但如果你是在一个已有的项目当中引入 React 的话,你可能会需要在不同的部分单独定义 React 根节点。 要将React元素渲染到根DOM节点中,我们通过把它们都传递给 ReactDOM.render() 的方法来将其渲染到页面上:

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

更新元素渲染

React 元素都是不可变的。当元素被创建之后,你是无法改变其内容或属性的。

目前更新界面的唯一办法是创建一个新的元素,然后将它传入 ReactDOM.render() 方法: React 只会更新必要的部分,值得注意的是 React DOM 首先会比较元素内容先后的不同,而在渲染过程中只会更新改变了的部分。

React JSX

React 使用 JSX 来替代常规的 JavaScript。

JSX 是一个看起来很像 XML 的 JavaScript 语法扩展。

我们不需要一定使用 JSX,但它有以下优点:

1.JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。

2.它是类型安全的,在编译过程中就能发现错误。

3.使用 JSX 编写模板更加简单快速。

我们先看下以下代码:

    const element = <h1>Hello, world!</h1>;

这种看起来可能有些奇怪的标签语法既不是字符串也不是 HTML。

它被称为 JSX, 一种 JavaScript 的语法扩展。 我们推荐在 React 中使用 JSX 来描述用户界面。

JSX 是在 JavaScript 内部实现的。

我们知道元素是构成 React 应用的最小单位,JSX 就是用来声明 React 当中的元素。与浏览器的 DOM 元素不同,React 当中的元素事实上是普通的对象,React DOM 可以确保 浏览器 DOM 的数据内容与 React 元素保持一致。 要将 React 元素渲染到根 DOM 节点中,我们通过把它们都传递给 ReactDOM.render() 的方法来将其渲染到页面上:

    var myDivElement = <div className="foo" />;
    ReactDOM.render(myDivElement, document.getElementById('example'));

注意:由于 JSX 就是 JavaScript,一些标识符像 class 和 for 不建议作为 XML 属性名。作为替代,React DOM 使用 className 和 htmlFor 来做对应的属性。

使用 JSX

JSX 看起来类似 HTML ,我们可以看下实例:

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

我们可以在以上代码中嵌套多个 HTML 标签,需要使用一个 div 元素包裹它,实例中的 p 元素添加了自定义属性 data-myattribute,添加自定义属性需要使用 data- 前缀。

    ReactDOM.render(
    <div>
    <h1>GodYue</h1>
    <h2>欢迎学习 React</h2>
    <p data-myattribute = "somevalue">这是一个很不错的 JavaScript 库!</p>
    </div>
    ,
    document.getElementById('example')
    );

独立文件

你的 React JSX 代码可以放在一个独立文件上,例如我们创建一个 helloworld_react.js 文件

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

然后在 HTML 文件中引入该 JS 文件

    <body>
    <div id="example"></div>
    <script type="text/babel" src="helloworld_react.js"></script>
    </body>

JavaScript 表达式

我们可以在 JSX 中使用 JavaScript 表达式。表达式写在花括号 {} 中。

在 JSX 中不能使用 if else 语句,但可以使用 conditional (三元运算) 表达式来替代。以下实例中如果变量 i 等于 1 浏览器将输出 true, 如果修改 i 的值,则会输出 false.

    ReactDOM.render(
    <div>
    <h1>{i == 1 ? 'True!' : 'False'}</h1>
    </div>
    ,
    document.getElementById('example')
    );

样式

React 推荐使用内联样式。我们可以使用 camelCase 语法来设置内联样式. React 会在指定元素数字后自动添加 px 。以下实例演示了为 h1 元素添加 myStyle 内联样式

    var myStyle = {
    fontSize: 100,
    color: '#FF0000'
    };
    ReactDOM.render(
    <h1 style = {myStyle}>菜鸟教程</h1>,
    document.getElementById('example')
);

注释

注释需要写在花括号中

数组

JSX 允许在模板中插入数组,数组会自动展开所有成员

    var arr = [
    <h1>你知道吗</h1>,
    <h2>你就要成功了!</h2>,
    ];
    ReactDOM.render(
    <div>{arr}</div>,
    document.getElementById('example')
    );

React 组件

我们封装一个输出 "Hello World!" 的组件,组件名为 HelloMessage

1、我们可以使用函数定义了一个组件:

    function HelloMessage(props) {
    return <h1>Hello World!</h1>;
    }

2.也可以使用 ES6 class 来定义一个组件

    class Welcome extends React.Component {
    render() {
    return <h1>Hello World!</h1>;
    }
    }

3.const element = <HelloMessage /> 为用户自定义的组件

复合组件

我们可以通过创建多个组件来合成一个组件,即把组件的不同功能点进行分离。

    function Name(props) {
    return <h1>网站名称:{props.name}</h1>;
    }
    function Url(props) {
    return <h1>网站地址:{props.url}</h1>;
    }
    function Nickname(props) {
    return <h1>网站小名:{props.nickname}</h1>;
    }
    function App() {
    return (
    <div>
    <Name name="菜鸟教程" />
    <Url url="http://www.runoob.com" />
    <Nickname nickname="Runoob" />
    </div>
    );
    }

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

App 组件使用了 Name、Url 和 Nickname 组件来输出对应的信息。

React State(状态)

React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。

React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。

以下实例创建一个名称扩展为 React.Component 的 ES6 类,在 render() 方法中使用 this.state 来修改当前的时间。

添加一个类构造函数来初始化状态 this.state,类组件应始终使用 props 调用基础构造函数。

    class Clock extends React.Component {
      constructor(props) {
        super(props);
        this.state = {date: new Date()};
      }
     
      render() {
        return (
          <div>
            <h1>Hello, world!</h1>
            <h2>现在是 {this.state.date.toLocaleTimeString()}.</h2>
          </div>
        );
      }
    }
     
    ReactDOM.render(
      <Clock />,
      document.getElementById('example')
    );

将生命周期方法添加到类中

在具有许多组件的应用程序中,在销毁时释放组件所占用的资源非常重要。 每当 Clock 组件第一次加载到 DOM 中的时候,我们都想生成定时器,这在 React 中被称为挂载。 同样,每当 Clock 生成的这个 DOM 被移除的时候,我们也会想要清除定时器,这在 React 中被称为卸载。 我们可以在组件类上声明特殊的方法,当组件挂载或卸载时,来运行一些代码

    class Clock extends React.Component {
      constructor(props) {
        super(props);
        this.state = {date: new Date()};
      }
     
      componentDidMount() {
        this.timerID = setInterval(
          () => this.tick(),
          1000
        );
      }
     
      componentWillUnmount() {
        clearInterval(this.timerID);
      }
     
      tick() {
        this.setState({
          date: new Date()
        });
      }
     
      render() {
        return (
          <div>
            <h1>Hello, world!</h1>
            <h2>现在是 {this.state.date.toLocaleTimeString()}.</h2>
          </div>
        );
      }
    }
     
    ReactDOM.render(
      <Clock />,
      document.getElementById('example')
    );

componentDidMount() 与 componentWillUnmount() 方法被称作生命周期钩子。

在组件输出到 DOM 后会执行 componentDidMount() 钩子,我们就可以在这个钩子上设置一个定时器。

this.timerID 为定时器的 ID,我们可以在 componentWillUnmount() 钩子中卸载定时器。

代码执行顺序:

1.当 <Clock /> 被传递给 ReactDOM.render() 时,React 调用 Clock 组件的构造函数。 由于 Clock 需要显示当前时间,所以使用包含当前时间的对象来初始化 this.state 。 我们稍后会更新此状态。

2.React 然后调用 Clock 组件的 render() 方法。这是 React 了解屏幕上应该显示什么内容,然后 React 更新 DOM 以匹配 Clock 的渲染输出。

3.当 Clock 的输出插入到 DOM 中时,React 调用 componentDidMount() 生命周期钩子。 在其中,Clock 组件要求浏览器设置一个定时器,每秒钟调用一次 tick()。

4.浏览器每秒钟调用 tick() 方法。 在其中,Clock 组件通过使用包含当前时间的对象调用 setState() 来调度UI更新。 通过调用 setState() ,React 知道状态已经改变,并再次调用 render() 方法来确定屏幕上应当显示什么。 这一次,render() 方法中的 this.state.date 将不同,所以渲染输出将包含更新的时间,并相应地更新 DOM。

5.一旦 Clock 组件被从 DOM 中移除,React 会调用 componentWillUnmount() 这个钩子函数,定时器也就会被清除。

                                                                                                            未完待续。。。