Skip to content

Latest commit

 

History

History
151 lines (116 loc) · 6.81 KB

1.first.md

File metadata and controls

151 lines (116 loc) · 6.81 KB

初识

react 是什么

react 是用于构建用户界面的JavaScript 库。

react 开发依赖

  • 开发React必须依赖三个库:

    • react:包含react所必须的核心代码
    • react-dom:react渲染在不同平台所需要的核心代码
    • babel:将jsx转换成React代码的工具
  • 第一次接触React会被它繁琐的依赖搞蒙,对于Vue来说,我们只是依赖一个vue.js文件即可,但是react居然要依赖三个库。其实呢,这三个库是各司其职的,目的就是让每一个库只单纯做自己的事情:在React的0.14版本之前是没有react-dom这个概念的,所有功能都包含在react里。为什么要进行拆分呢?原因就是react-native。react包中包含了react和react-native所共同拥有的核心代码。

  • react-dom针对web和native所完成的事情不同:

    • web端:react-dom会讲jsx最终渲染成真实的DOM,显示在浏览器中
    • native端:react-dom会讲jsx最终渲染成原生的控件(比如Android中的Button,iOS中的UIButton)。
  • React和Babel的关系:默认情况下开发React其实可以不使用babel。但是前提是我们自己使用React.createElement 来编写源代码,它编写的代码非常的繁琐和可读性差。那么我们就可以直接编写jsx(JavaScript XML)的语法,并且让babel帮助我们转换成React.createElement。后续还会讲到;

引入React依赖

  • 那么,如何添加这三个依赖:
    • 方式一:直接CDN引入
    • 方式二:下载后,添加本地依赖
    • 方式三:通过npm管理(后续脚手架再使用)

暂时我们直接通过CDN引入,来演练下面的示例程序:这里有一个crossorigin的属性,这个属性的目的是为了拿到跨域脚本的错误信息

<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

hello world

第一步:在界面上通过React显示一个Hello World

  • 注意:这里我们编写React的script代码中,必须添加type="text/babel",作用是可以让babel解析jsx的语法
  • ReactDOM.render函数:
    • 参数一:传递要渲染的内容,这个内容可以是HTML元素,也可以是React的组件。这里我们传入了一个h2元素,后面我们就会使用React组件
    • 参数二:将渲染的内容,挂载到哪一个HTML元素上。这里我们已经提定义一个id为app的div,我们可以通过{}语法来引入外部的变量或者表达式
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app"></div>

    <!-- react 依赖 -->
    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

    <!-- 使用 jsx 并且希望 script 标签中的 jsx 被解析,需要添加一个属性 -->
    <!-- jsx 多个标签最外层只能有一个标签 -->
    <script type="text/babel">
        // ReactDOM.render(渲染的内容(jsx 代码), 挂载的对象, )

        // ReactDOM.render(<h2>hello world</h2>, document.getElementById('app'));

        let message = 'Hello World';

        function btnClick () {
            message = 'Hello React';
            render();
        }

        function render () {
            ReactDOM.render(
                <div>
                    <h2>{message}</h2>
                    <button onClick={btnClick}>改变文本</button>
                </div>, 
                document.getElementById('app')
            );
        }
        
        render();
    </script>
</body>
</html>

组件化

  • 整个逻辑其实可以看做一个整体,那么我们就可以将其封装成一个组件:我们说过ReactDOM.render 第一参数是一个HTML原生或者一个组件;所以我们可以先将之前的业务逻辑封装到一个组件中,然后传入到ReactDOM.render 函数中的第一个参数;在React中,如何封装一个组件呢?这里我们暂时使用类的方式封装组件:

    1. 定义一个类(类名大写,组件的名称是必须大写的,小写会被认为是HTML元素),继承自React.Component
    2. 实现当前组件的render函数
    3. render当中返回的jsx内容,就是之后React会帮助我们渲染的内容
  • 组件化问题二:事件绑定中的this。在类中直接定义一个函数,并且将这个函数绑定到html原生的onClick事件上,当前这个函数的this指向的是谁呢?默认情况下是undefined很奇怪,居然是undefined;因为在正常的DOM操作中,监听点击,监听函数中的this其实是节点对象(比如说是button对象);这次因为React并不是直接渲染成真实的DOM,我们所编写的button只是一个语法糖,它的本质React的Element对象;那么在这里发生监听的时候,react给我们的函数绑定的this,默认情况下就是一个undefined;我们在绑定的函数中,可能想要使用当前对象,比如执行this.setState 函数,就必须拿到当前对象的this我们就需要在传入函数时,给这个函数直接绑定this。类似于下面的写法:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app"></div>

    <script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>

    <script type="text/babel">

        class App extends React.Component {
            
            constructor () {
                super();
                this.state = {
                    message: 'Hello World'
                }
            }

            btnClick () {
                this.setState({
                    message: 'Hello React'
                })
            }

            render () {
                return (
                    <div>
                        <h2>{this.state.message}</h2>
                        <button onClick={this.btnClick.bind(this)}>改变文本</button>
                    </div>
                )
            }

        }

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