
2013 年被开源,2014 年在中国彻底火爆。 文档: https://reactjs.org/docs/hello-world.html
这是一个最最简单的一个 react 起步的语句,当然一些 webpack、babel 的配置昨天已经花了一天时间讲解,不说了。 import React from "react"; import ReactDOM from "react-dom";
ReactDOM.render(
两个坑: 1 )注意,所有的 jsx 语法必须被一个独立的、唯一的标签包裹。
2)第二个参数没有分号
在手册上学习一些理论知识(面试用): The react-dom package provides DOM-specific methods that can be used at the top level of your app and as an escape hatch to get outside of the React model if you need to. react-dom 这个包提供了你的 app 的最高等级的 API,提供了元素的挂载和上树的方法。
Render a React element into the DOM in the supplied container and return a reference to the component Render 方法接收两个参数,第二个参数是挂载点,第一个参数是 react 元素,用来让 react 元素进行挂载。
1.1 组件 1.1.1 类式组件 创建 App.js 文件,必须按要求书写标准壳,这个壳子叫做 rcc 壳,react class component,react 的类式组件。 import React from "react";
export default class App extends React.Component{ constructor(){ super(); }
render(){ return <div> <h1>我是 App 组件,你好!!</h1> </div> } } 注意: 1 )这个文件的默认暴露就是一个类,这个类的类名必须和文件名相同。 2 )文件名和类名的首字母必须大写! React 中一个组件的合法名字的首字母必须是大写字母。 3 )这个类必须继承自 React.Component 类,也就是说,一个 rcc 壳必须有 extends React.Component 的写法。 4 )这个类必须有构造器 constructor,构造器里面必须调用超类的构造器,super(); 5 )这个类必须有 render 函数,render 函数中必须 return 一个 jsx 对象。同样的,这个 jsx 对象必须被唯一的标签包裹。
使用组件,比如我们现在在 main.js 中使用组件: import React from "react"; import ReactDOM from "react-dom";
import App from "./App.js";
ReactDOM.render( <app></app> , document.getElementById("app") ); 注意: 1 )引入的组件必须路径以./开头 2 )你的组件要使用,就将这个组件的名字(类名、文件名)进行标签化即可。 机理就是这个 App 类在被实例化。
安装插件之后,输入 rcc 即可快速展开一个组件。
react 中允许组件套用组件,方法一样,用 rcc 写组件的壳子,注意一些注意的问题。 然后进行引入,用标签进行实例化。 定义组件 使用组件
1.1.2 函数式组件 只要一个函数,能够返回 jsx,此时我们把这个函数也叫作组件。
import React from "react";
import Canlendar from "./components/Canlendar.js";
export default class App extends React.Component{ constructor(){ super(); }
render(){ const Haha = () => { return <div> <h1>我是哈哈组件</h1> </div> } return <div> <h1>我是 App 组件,你好!!</h1> <Canlendar></Canlendar> <Haha></Haha> </div> } } 注意: 1 ) render 是一个函数,所以函数里面当然可以定义另一个函数。我们用 const 来定义一个箭头函数,这个箭头函数的名字,必须首字母大写。react 中所有标签名字是首字母大写的,将被判定为我们自己的组件。 2 )这个函数里面 return 了一个 jsx 对象,注意,不要加引号。初学者会有很多不适。 3 )这个组件也是通过“标签”的形式来上树的! 4 )函数式组件比类组件差很多功能很过,今后讲。 5 )至于什么时候用什么组件、圆括号中能不能传入参数,今后的课程讲。
1.2 jsx 语法(重点) jsx 语法出现在 render 的 return 后面:
1.2.1 标签必须严格关闭 比如下面的 p 标签没有结束标签,将产生错误,此时页面什么都不显示。 import React from "react";
export default class App extends React.Component{ constructor(){ super(); }
render(){ return <div> <h1>我是 App 组件,你好!!</h1> <p>哈哈 </div> } }
一定要注意单封闭标签,必须有反斜杠,否则将产生错误,此时页面什么都不显示
1.2.2 标签必须合理嵌套 比如 table 不能直接携带 tr,必须要有 tbody: import React from "react";
export default class App extends React.Component{ constructor(){ super(); }
render(){ return <div> <table> <tbody> <tr> <td>1</td> <td>2</td> <td>3</td> </tr> </tbody> </table> </div> } }
比如这是错误的:
1.2.3 所有的类名必须用 className 表示,for 用 htmlFor 表示 因为 js 中 class 是关键字,所以必须用 className 来避讳一下:
for 要用 htmlFor 代替 <label htmlfor=""></label>
1.2.4 插值初步(重点) 我们可以在 jsx 的内部,用{}单大括号进行一些 js 表达式的插入,我们叫做插值。 import React from "react";
export default class App extends React.Component{ constructor(){ super(); }
render(){ return <div> <h1>我爱你 10000 年</h1> <h1>我爱你{5000 * 2}年</h1> <h1>我爱你{10 * 10 * 10 * 10}年</h1> </div> } }
插值可以写什么? 简单的计算是可以的:
变量的插入是可以的: import React from "react";
export default class App extends React.Component{ constructor(){ super(); }
render(){ const year = 10000; return <div> <h1>我爱你 10000 年</h1> <h1>我爱你{5000 * 2}年</h1> <h1>我爱你{10 * 10 * 10 * 10}年</h1> <h1>我爱你{year}年</h1> </div> } }
函数的调用是可以的: import React from "react";
export default class App extends React.Component{ constructor(){ super(); }
render(){ const year = 10000; const pingfang = (n) => { return n * n; } return <div> <h1>我爱你 10000 年</h1> <h1>我爱你{5000 * 2}年</h1> <h1>我爱你{10 * 10 * 10 * 10}年</h1> <h1>我爱你{year}年</h1> <h1>我爱你{pingfang(100)}年</h1> </div> } }
三元运算符是可以的:
内置对象的调用是可以的:
表达式级别的函数是可以的: import React from "react";
export default class App extends React.Component{ constructor(){ super(); }
render(){ const year = 10000; const pingfang = (n) => { return n * n; } const arr = [1000 , 2000 , 3000 , 4000]; return <div> <h1>我爱你 10000 年</h1> <h1>我爱你{5000 * 2}年</h1> <h1>我爱你{10 * 10 * 10 * 10}年</h1> <h1>我爱你{year}年</h1> <h1>我爱你{pingfang(100)}年</h1> <h1>我爱你{3 > 8 ? 8000 : 10000}年</h1> <h1>我爱你{parseInt(Math.random() * 10000)}年</h1> <h1>我爱你{arr.reduce((a,b)=>a + b)}年</h1> </div> } }
不能进行插值的是: if 语句、for 循环、while 循环、do …… while 循环都不行!
不能定义变量,不能定义函数。
不能放置 JSON、数组(一会儿你将知道数组有特别的意义): import React from "react";
export default class App extends React.Component{ constructor(){ super(); }
render(){ var obj = {"a" : 1 , "b" : 2} return <div> {obj} </div> } } 此时会报大错。 如果就是想在页面上显示 json,要用 JSON.stringify(obj)
1.2.5 插值高级(难点) 引号内的插值,去掉引号!!!变为{},内部继续使用引号拼接字符串。
import React from "react";
export default class App extends React.Component{ constructor(){ super(); }
render(){ const imgtitle= "baby"; return <div> <img src={`/images/${imgtitle}.png`} alt=""/> </div> } }
import React from "react";
export default class App extends React.Component{ constructor(){ super(); }
render(){ const imgtitle= "baby"; const shui = "我老婆" return <div> <img src={`/images/${imgtitle}.png`} title={shui} /> </div> } }
React 的沮丧感很大!!一定要注意细节,要不然真到大项目开发的时候,就很崩溃。
import React from "react";
export default class App extends React.Component{ constructor(){ super(); }
render(){ const imgtitle= "baby"; const shui = "我老婆" const qunaer = "http://www.163.com"; return <div> <img src={`/images/${imgtitle}.png`} title={shui} /> <a href={qunaer}>点击我去网易</a> </div> } }
内嵌样式要求有这样的语法插值: style 后面直接跟着{{}},没有引号。 {{}}里面是标准 json,所有的属性名都是驼峰命名法:
react 的程序,可以进行合理的换行,多写就有感觉了。react 程序行文很漂亮。
1.3 jsx 中的数组自动展开(五星重点、五星难点) 1.3.1 认识数组的自动展开特性 import React from "react";
export default class App extends React.Component{ constructor(){ super(); }
render(){ const arr = [ <li key="0">牛奶</li>, <li key="1">咖啡</li>, <li key="2">奶茶</li>, <li key="3">可乐</li> ]; return <div> <ul> {arr} </ul> </div> } } 注意: 1 )数组有 4 项,每项都是 jsx 元素,不需要引号的; 2 )每一个项必须要有不同 key 属性,这是 react 要求,没有什么好说的; 3 )数组直接{arr}写就行了,不需要{arr()}、也不需要写遍历语句什么的。
1.3.2 会用 map 给每一个项包裹标签 我们给你的数据,没有任何的标签对儿,只是数据。 此时就要在{}中用 map 来映射出一个数组(我们之前讲过,表达式语义 map、filter、reduce 都可以用哦)。
import React from "react";
export default class App extends React.Component{ constructor(){ super(); }
render(){ const arr = ["牛奶","咖啡","奶茶","可乐"]; return <div> <ul> { arr.map((item,index)=>{ return <li key={index}>{item}</li> }) } </ul> </div> } }
1.3.3 映射出一个表格
import React from "react";
export default class App extends React.Component{ constructor(){ super(); }
render(){ const arr = [ {"id" : 1 , "name" : "小明" , "age" : 12 , "sex" : "男"}, {"id" : 2 , "name" : "小红" , "age" : 13 , "sex" : "女"}, {"id" : 3 , "name" : "小刚" , "age" : 11 , "sex" : "男"}, {"id" : 4 , "name" : "小强" , "age" : 9 , "sex" : "男"} ]; return <div> <table> <tbody> { arr.map(item => { return <tr key={item.id}> <td>{item.id}</td> <td>{item.name}</td> <td>{item.age}</td> <td>{item.sex}</td> </tr> }) } </tbody> </table> </div> } }
1.3.4 九九乘法表
import React from "react";
export default class App extends React.Component{ constructor(){ super(); }
render(){ const showJiujiu = () => { var arr = []; for(var i = 1 ; i <= 9 ; i++){ var temp = []; for (var j = 1; j <= 9; j++) { temp.push(<td key={j}>{j} * {i} = {i * j}</td>) } arr.push(<tr key={i}>{temp}</tr>) } return arr; } return <div> <table> <tbody> {showJiujiu()} </tbody> </table> </div> } }
1.3.5 月历 我们要在网页上显示一个月份的月历。
大概分为三部分: 1 )上个月的尾巴 2 )本月 3 )下个月的前奏
凭什么一个月的月历长成这样:
一个月的月历长成什么样,由三个要素决定: 1 )本月 1 号星期几 2 )上月有几天 3 )本月有几天
这三个要素,可以用奇淫技巧快速的得到。 比如,我们想知道 2018 年 3 月有几天,直接让机器算 2018 年的 4 月的 0 号即可。
因为月份从 0 开始,所以这里 3 实际上是四月。 import React from "react";
export default class App extends React.Component{ constructor(){ super();
} render(){ const showrili = () => { var arr = []; var year = 2018; var mOnth= 3; //真实月份,从 1 开始 //三要素 //本月 1 号星期几 var benyueyihaoxingqiji = new Date(year , month - 1 , 1).getDay(); //getDay()表示得到星期 //本月有几天 var benyueyoujitian = new Date(year , month - 1 + 1 , 0).getDate(); //上月有几天 var shangyueyoujitian = new Date(year , month - 1 , 0).getDate(); //组建一个一维数组 var _arr = []; //本月 1 号星期几,就要往数组中放入几天上个月的尾巴。 for (var i = 0 ; i < benyueyihaoxingqiji ; i++){ _arr.unshift(shangyueyoujitian - i); } //本月有几天,数组中就要放入几天这个月 for(var i = 1 ; i <= benyueyoujitian ; i++){ _arr.push(i); } //凑满 42 项 var count = 1; while(_arr.length != 42){ _arr.push(count++); } //将一个一维数组,变为二维数组 for(var i = 0 ; i < 6 ; i++){ arr.push( <tr key={i}> { _arr.slice(i * 7 , i * 7 + 7).map((item,index)=>{ return <td key={index}>{_arr[i * 7 + index]}</td> }) } </tr> ) } return arr; } return <div> <table> <tbody> {showrili()} </tbody> </table> </div> } }