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>
}
}
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.