第1章:React入门

362 阅读6分钟

1.1 hello_react案例

概要总结

1、React依赖库介绍

2、hello_react案例

一、React所需的依赖库介绍

1、babel.min.js

babel库可以把ES6语法转成ES5,而且在模块化引入语句import也需要babel进行转换。除此之外,写React的是jsx,但浏览器只认js,babel也能将jsx转成js。

2、react.development.js

React核心库。

3、react-dom.development.js

使用React我们就不需要操作Dom了,由React来操作,它需要借助这个库的支持,它属于React的扩展库。

二、hello_react案例

1、准备一个"容器"

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>hello_react</title>
</head>
<body>
  <!-- 准备好一个"容器" -->
  <div id="test"></div>
</body>
</html>

2、引入3个依赖库

react.development.js必须要在react-dom.development.js之前引入,因为react.development.js是核心库,只有核心库引入了,扩展库才能引入。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>hello_react</title>
</head>
<body>
  <!-- 准备好一个"容器" -->
  <div id="test"></div>

  <!-- 引入React核心库 -->
  <script type="text/javascript" src="../js/react.development.js"></script>
  <!-- 引入react-dom,用于支持react操作DOM -->
  <script type="text/javascript" src="../js/react-dom.development.js"></script>
  <!-- 引入babel,用于将jsx转为js -->
  <script type="text/javascript" src="../js/babel.min.js"></script>
</body>
</html>

3、定义<script>标签类型

<script>默认类型为text/javascript,现在写jsx,因此要设定类型为text/babel。表示里面写的不再是js,而是jsx,需要靠babel转义。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>hello_react</title>
</head>
<body>
  <!-- 准备好一个"容器" -->
  <div id="test"></div>

  <!-- 引入React核心库 -->
  <script type="text/javascript" src="../js/react.development.js"></script>
  <!-- 引入react-dom,用于支持react操作DOM -->
  <script type="text/javascript" src="../js/react-dom.development.js"></script>
  <!-- 引入babel,用于将jsx转为js -->
  <script type="text/javascript" src="../js/babel.min.js"></script>
  
  <script type="text/babel">    /* 此处一定要写babel */
  
  </script>
</body>
</html>

4、创建虚拟DOM

注意:这里千万不要加上引号,因为这里不是js,而是jsx。

<script type="text/babel">    /* 此处一定要写babel */
  // 1.创建虚拟DOM
  const VDOM = <h1>hello,React</h1>   /* 此处一定不要写引号,因为不是字符串 */
</script>

5、渲染虚拟DOM到页面

通过ReactDOM的render函数进行渲染,render函数有两个参数,第一个是虚拟DOM,第二个是容器。

<script type="text/babel">    /* 此处一定要写babel */
  // 1.创建虚拟DOM
  const VDOM = <h1>hello,React</h1>   /* 此处一定不要写引号,因为不是字符串 */
  // 2.渲染虚拟DOM到页面
  ReactDOM.render(VDOM, document.getElementById('test'))
</script>

1.2 虚拟DOM的两种创建方式

概要总结

1、纯JS创建虚拟DOM(不推荐)

2、JSX创建虚拟DOM

3、纯JS与JSX比较

需求:创建一个h1标签,并带有id属性为title。

一、纯JS方式

对于原生js而言,可以不引入babel库,因为它没使用jsx不需要转换。

在document对象有createElement方法来创建元素,在React对象也有相同的方法。document的方法是创建真实DOM,而React的方法是用来创建虚拟DOM。React的createElement方法有几个参数:标签名、标签属性、标签内容。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>2_使用JS创建虚拟DOM</title>
</head>
<body>
  <!-- 准备好一个"容器" -->
  <div id="test"></div>

  <!-- 引入React核心库 -->
  <script type="text/javascript" src="../js/react.development.js"></script>
  <!-- 引入react-dom,用于支持react操作DOM -->
  <script type="text/javascript" src="../js/react-dom.development.js"></script>

  <script type="text/javascript">
    // 1.创建虚拟DOM
    const VDOM = React.createElement('h1', {id: 'title'}, 'Hello_React')
    // 2.渲染虚拟DOM到页面
    ReactDOM.render(VDOM, document.getElementById('test'))
  </script>
</body>
</html>

二、JSX方式

对于JSX而言,HTML是什么结构,在JSX里也就是什么结构,完全一致。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>hello_react</title>
</head>
<body>
  <!-- 准备好一个"容器" -->
  <div id="test"></div>

  <!-- 引入React核心库 -->
  <script type="text/javascript" src="../js/react.development.js"></script>
  <!-- 引入react-dom,用于支持react操作DOM -->
  <script type="text/javascript" src="../js/react-dom.development.js"></script>
  <!-- 引入babel,用于将jsx转为js -->
  <script type="text/javascript" src="../js/babel.min.js"></script>
  
  <script type="text/babel">    /* 此处一定要写babel */
    // 1.创建虚拟DOM
    const VDOM = <h1 id="title">hello,React</h1>   /* 此处一定不要写引号,因为不是字符串 */
    // 2.渲染虚拟DOM到页面
    ReactDOM.render(VDOM, document.getElementById('test'))
  </script>
</body>
</html>

三、两种方式比较

两种方式都能创建虚拟DOM,但面对复杂的DOM结构,假如需要在h1标签里再套一层span标签,纯JS方式就显得非常臃肿。

1、纯JS

<script type="text/javascript">
  // 1.创建虚拟DOM
  const VDOM = React.createElement('h1', {id: 'title'}, React.createElement('span', {}, 'Hello,React'))
  // 2.渲染虚拟DOM到页面
  ReactDOM.render(VDOM, document.getElementById('test'))
</script>

2、JSX

在JSX里写虚拟DOM,就如同在写HTML一样:

<script type="text/babel">    /* 此处一定要写babel */
  // 1.创建虚拟DOM
  const VDOM = (   /* 此处一定不要写引号,因为不是字符串 */
    <h1 id="title">
      <span>hello,React</span>
    </h1>
  )
  // 2.渲染虚拟DOM到页面
  ReactDOM.render(VDOM, document.getElementById('test'))
</script>

总结:JSX就是为了解决虚拟DOM太过繁琐的问题,它能让编码人员更加简单的创建虚拟DOM。它经过babel翻译之后,实际上就会变成了纯JS创建虚拟DOM的方式,因此JSX实际上就是纯JS创建虚拟DOM的语法糖。

1.3 虚拟DOM与真实DOM

概要总结

1、虚拟DOM也是一个对象

2、虚拟DOM比真实DOM少了很多属性,因为它只是给React内部使用,无需挂载过多的属性

一、虚拟DOM的类型

虚拟DOM实际上就是一个对象,无论使用typeof还是instanceof,结果还是对象。

<script type="text/babel">    /* 此处一定要写babel */
  // 1.创建虚拟DOM
  const VDOM = (   /* 此处一定不要写引号,因为不是字符串 */
    <h1 id="title">
      <span>hello,React</span>
    </h1>
  )
  // 2.渲染虚拟DOM到页面
  ReactDOM.render(VDOM, document.getElementById('test'))

  console.log('虚拟DOM', VDOM)    // 虚拟DOM Object
  console.log(typeof VDOM)    // object
  console.log(VDOM instanceof Object)    // true
</script>

二、虚拟DOM与真实DOM的对比

<!-- 准备好一个"容器" -->
<div id="test"></div>
<div id="demo"></div>

<script type="text/babel">    /* 此处一定要写babel */
  // 1.创建虚拟DOM
  const VDOM = (   /* 此处一定不要写引号,因为不是字符串 */
    <h1 id="title">
      <span>hello,React</span>
    </h1>
  )
  // 2.渲染虚拟DOM到页面
  ReactDOM.render(VDOM, document.getElementById('test'))

  const TDOM = document.getElementById('demo')
  console.log('虚拟DOM', VDOM)
  console.log('真实DOM', TDOM)
</script>

通过debugger断点可以查看两个对象的属性:

虚拟DOM比较“轻”,真实DOM比较“重”,因为虚拟DOM是React内部在用,无需真实DOM上那么多的属性。

1.4 jsx语法规则

概要总结

1、定义虚拟DOM时,不要写引号

2、标签中混入JS表达式时要用花括号

3、样式的类名指定不要用class,要用className

4、内联样式,要用style={{key: value}}的形式去写

5、只有一个根标签

6、标签必须闭合

7、标签首字母

(1)若小写字母开头,则将该标签转为html中同名元素,若html中无该标签对应的同名元素,则报错

(2)若大写字母开头,react就去渲染对应的组件,若组件没有定义,则报错

一、定义虚拟DOM时,不要写引号

<script type="text/babel">    /* 此处一定要写babel */
  // 1.创建虚拟DOM
  const VDOM = (   /* 此处一定不要写引号,因为不是字符串 */
    <h2 id="atguigu">
      <span>hello,react</span>
    </h2>
  )
  // 2.渲染虚拟DOM到页面
  ReactDOM.render(VDOM, document.getElementById('test'))
</script>

二、标签中混入JS表达式时要用花括号

<script type="text/babel">    /* 此处一定要写babel */
  const myId = 'aTgUiGu'
  const myData = 'HeLlo,rEaCt'
  // 1.创建虚拟DOM
  const VDOM = (   /* 此处一定不要写引号,因为不是字符串 */
    <h2 id={myId.toLowerCase()}>
      <span>{myData.toLowerCase()}</span>
    </h2>
  )
  // 2.渲染虚拟DOM到页面
  ReactDOM.render(VDOM, document.getElementById('test'))
</script>

三、样式的类名指定不要用class,要用className

<style>
  .title {
    background-color: orange;
    width: 200px;
  }
</style>
<script type="text/babel">    /* 此处一定要写babel */
  const myId = 'aTgUiGu'
  const myData = 'HeLlo,rEaCt'
  // 1.创建虚拟DOM
  const VDOM = (   /* 此处一定不要写引号,因为不是字符串 */
    <h2 class="title" id={myId.toLowerCase()}>
      <span>{myData.toLowerCase()}</span>
    </h2>
  )
  // 2.渲染虚拟DOM到页面
  ReactDOM.render(VDOM, document.getElementById('test'))
</script>

直接用class它也能显示,但控制台会提示使用className,因为class在es6中属于关键字,React避开这个关键字而使用了className。

<script type="text/babel">    /* 此处一定要写babel */
  const myId = 'aTgUiGu'
  const myData = 'HeLlo,rEaCt'
  // 1.创建虚拟DOM
  const VDOM = (   /* 此处一定不要写引号,因为不是字符串 */
    <h2 className="title" id={myId.toLowerCase()}>
      <span>{myData.toLowerCase()}</span>
    </h2>
  )
  // 2.渲染虚拟DOM到页面
  ReactDOM.render(VDOM, document.getElementById('test'))
</script>

四、内联样式,要用style={{key: value}}的形式去写

<script type="text/babel">    /* 此处一定要写babel */
  const myId = 'aTgUiGu'
  const myData = 'HeLlo,rEaCt'
  // 1.创建虚拟DOM
  const VDOM = (   /* 此处一定不要写引号,因为不是字符串 */
    <h2 className="title" id={myId.toLowerCase()}>
      <span style={{color: 'white', fontSize: '29px'}}>{myData.toLowerCase()}</span>
    </h2>
  )
  // 2.渲染虚拟DOM到页面
  ReactDOM.render(VDOM, document.getElementById('test'))
</script>

注意:它跟html的style写法不一样,在html的style里,里面写的是一个字符串,用分号隔开,可以写多组样式;而在jsx里,它需要用两个花括号包裹,最外面的花括号代表里面是一个js表达式,里面的花括号代表它是一个对象,里面写的是样式的键值对。

五、只有一个根标签

在jsx语法里,不允许有多个根标签,只允许出现一个。如果有多个标签出现,需要在最外层再包裹一个元素作为根标签。

<script type="text/babel">    /* 此处一定要写babel */
  const myId = 'aTgUiGu'
  const myData = 'HeLlo,rEaCt'
  // 1.创建虚拟DOM
  const VDOM = (   /* 此处一定不要写引号,因为不是字符串 */
    <div>
      <h2 className="title" id={myId.toLowerCase()}>
        <span style={{color: 'white', fontSize: '29px'}}>{myData.toLowerCase()}</span>
      </h2>
      <h2 className="title" id={myId.toUpperCase()}>
        <span style={{color: 'white', fontSize: '29px'}}>{myData.toLowerCase()}</span>
      </h2>
    </div>
  )
  // 2.渲染虚拟DOM到页面
  ReactDOM.render(VDOM, document.getElementById('test'))
</script>

六、标签必须闭合

在jsx语法里,所有的标签都必须要有闭合,否则也会报错。

<script type="text/babel">    /* 此处一定要写babel */
  const myId = 'aTgUiGu'
  const myData = 'HeLlo,rEaCt'
  // 1.创建虚拟DOM
  const VDOM = (   /* 此处一定不要写引号,因为不是字符串 */
    <div>
      <h2 className="title" id={myId.toLowerCase()}>
        <span style={{color: 'white', fontSize: '29px'}}>{myData.toLowerCase()}</span>
      </h2>
      <h2 className="title" id={myId.toUpperCase()}>
        <span style={{color: 'white', fontSize: '29px'}}>{myData.toLowerCase()}</span>
      </h2>
      <input type="text"/>
    </div>
  )
  // 2.渲染虚拟DOM到页面
  ReactDOM.render(VDOM, document.getElementById('test'))
</script>

七、标签首字母

1、若小写字母开头,则将该标签转为html中同名元素,若html中无该标签对应的同名元素,则报错

<script type="text/babel">    /* 此处一定要写babel */
  const myId = 'aTgUiGu'
  const myData = 'HeLlo,rEaCt'
  // 1.创建虚拟DOM
  const VDOM = (   /* 此处一定不要写引号,因为不是字符串 */
    <div>
      <h2 className="title" id={myId.toLowerCase()}>
        <span style={{color: 'white', fontSize: '29px'}}>{myData.toLowerCase()}</span>
      </h2>
      <h2 className="title" id={myId.toUpperCase()}>
        <span style={{color: 'white', fontSize: '29px'}}>{myData.toLowerCase()}</span>
      </h2>
      <input type="text"/>
      <good>123</good>
    </div>
  )
  // 2.渲染虚拟DOM到页面
  ReactDOM.render(VDOM, document.getElementById('test'))
</script>

这里写的good标签,很明显是无法对应html同名元素的,因此虽然它能显示出来,但是它还是会提出一个警告:

它的意思是:good标签无法被浏览器识别,如果你写的是React组件,那么首字母要大写。就是它除了报错以外,它会预判你如果是组件名,那么要求你首字母应该大写。

2、若大写字母开头,react就去渲染对应的组件,若组件没有定义,则报错

<script type="text/babel">    /* 此处一定要写babel */
  const myId = 'aTgUiGu'
  const myData = 'HeLlo,rEaCt'
  // 1.创建虚拟DOM
  const VDOM = (   /* 此处一定不要写引号,因为不是字符串 */
    <div>
      <h2 className="title" id={myId.toLowerCase()}>
        <span style={{color: 'white', fontSize: '29px'}}>{myData.toLowerCase()}</span>
      </h2>
      <h2 className="title" id={myId.toUpperCase()}>
        <span style={{color: 'white', fontSize: '29px'}}>{myData.toLowerCase()}</span>
      </h2>
      <input type="text"/>
      <Good>123</Good>
    </div>
  )
  // 2.渲染虚拟DOM到页面
  ReactDOM.render(VDOM, document.getElementById('test'))
</script>

这一回写的是Good标签,它不是弹出警告,而是直接报错Good未定义。因为它并不是去html转为同名元素,而是渲染React的同名组件,组件未定义就报错了。

1.5 jsx小练习

概要总结

1、js表达式与js语句

2、React能自动遍历数组,但不能遍历对象

需求:动态展示如下列表

一、使用虚拟DOM完成静态页面

<script type="text/babel">    /* 此处一定要写babel */
  // 1.创建虚拟DOM
  const VDOM = (   /* 此处一定不要写引号,因为不是字符串 */
    <div>
      <h1>前端js框架列表</h1>
      <ul>
        <li>Angular</li>
        <li>React</li>
        <li>Vue</li>
      </ul>
    </div>
  )
  // 2.渲染虚拟DOM到页面
  ReactDOM.render(VDOM, document.getElementById('test'))
</script>

二、React能自动遍历数组,但不能自动遍历对象

1、通过表达式写入数组

<script type="text/babel">    /* 此处一定要写babel */
  // 模拟一些数据
  const data = ['Angular', 'React', 'Vue']
  // 1.创建虚拟DOM
  const VDOM = (   /* 此处一定不要写引号,因为不是字符串 */
    <div>
      <h1>前端js框架列表</h1>
      <ul>
        {data}
      </ul>
    </div>
  )
  // 2.渲染虚拟DOM到页面
  ReactDOM.render(VDOM, document.getElementById('test'))
</script>

注意:直接传入数组没有经过遍历,React还是能把数组遍历出来。数组里有什么,它就遍历显示什么。

<script type="text/babel">    /* 此处一定要写babel */
  // 模拟一些数据
  // const data = ['Angular', 'React', 'Vue']
  const data1 = [<li>Angular</li>, <li>React</li>, <li>Vue</li>]
  // 1.创建虚拟DOM
  const VDOM = (   /* 此处一定不要写引号,因为不是字符串 */
    <div>
      <h1>前端js框架列表</h1>
      <ul>
        {data1}
      </ul>
    </div>
  )
  // 2.渲染虚拟DOM到页面
  ReactDOM.render(VDOM, document.getElementById('test'))
</script>

2、通过表达式写入对象

<script type="text/babel">    /* 此处一定要写babel */
  // 模拟一些数据
  const data2 = {name1: 'Angular', name2: 'React', name3: 'Vue'}
  // 1.创建虚拟DOM
  const VDOM = (   /* 此处一定不要写引号,因为不是字符串 */
    <div>
      <h1>前端js框架列表</h1>
      <ul>
        {data2}
      </ul>
    </div>
  )
  // 2.渲染虚拟DOM到页面
  ReactDOM.render(VDOM, document.getElementById('test'))
</script>

注意:直接传入对象,它会报错对象并不是React子节点,它只能找到name1、name2、name3这些key,如果你想渲染一个集合,请您使用数组代替。

三、区分js语句与js表达式

在jsx里只允许写js表达式,而不能写js语句。

1、js表达式

(1)a

(2)a+b

(3)demo(1)

(4)arr.map()

(5)function test() {}

2、语句(代码)

(1)if() {}

(2)for() {}

(3)switch() {case: xxx}

<script type="text/babel">
  // 模拟一些数据
  const data = ['Angular', 'React', 'Vue']
  // 1.创建虚拟DOM
  const VDOM = (   /* 此处一定不要写引号,因为不是字符串 */
    <div>
      <h1>前端js框架列表</h1>
      <ul>
        {
          data.map((item, index) => {
            return <li>{item}</li>
          })
        }
      </ul>
    </div>
  )
  // 2.渲染虚拟DOM到页面
  ReactDOM.render(VDOM, document.getElementById('test'))
</script>

这里它会提示数组的每一个元素都需要有一个唯一的key值,我们可以使用数组遍历的下标给予key值的设定。

<script type="text/babel">
  // 模拟一些数据
  const data = ['Angular', 'React', 'Vue']
  // 1.创建虚拟DOM
  const VDOM = (   /* 此处一定不要写引号,因为不是字符串 */
    <div>
      <h1>前端js框架列表</h1>
      <ul>
        {
          data.map((item, index) => {
            return <li key={index}>{item}</li>
          })
        }
      </ul>
    </div>
  )
  // 2.渲染虚拟DOM到页面
  ReactDOM.render(VDOM, document.getElementById('test'))
</script>

1.6 代码地址

gitee.com/huang_jing_…