React 是一个用于构建用户界面的 JavaScript 库。它起源于 Facebook 的外部我的项目,因为该公司对市场上所有 JavaScript MVC 框架都不称心,就决定本人写一套,用来架设 Instagram 的网站。做进去当前,发现这套货色很好用,就在 2013 年 5 月开源了。
本文的大部分内容都能够在 React 的官网文档上找到,如果你想更加系统地学习 React,强烈建议你浏览一下官网文档。
Hello Word
一个最简略的 React 实例如下:
index.html
<div id="root"></div>
index.js
const element = <h1>Hello, world!</h1>; # JSX
ReactDOM.render(
element,
document.getElementById('root')
);
下面的例子会在网页中打印出 Hello, world!
index.html 中定义了一个用作“根”DOM 节点的 <div>
元素,index.js 中应用 ReactDOM.render()
将一个 React 组件渲染到该“根”DOM 节点上。
index.js 文件的第一行有些特地,这种将 JS 与 html 混写在一起的语法是 JS 的一种扩大,被称为 JSX。因为这种将 html 元素和 JS 逻辑混写在一起形式可能很好地体现 React 的“组件化”设计思维,这里强烈推荐你在 React 中应用 JSX 语法,只管这不是必须的。
React 组件
在传统的前端开发形式中,html 与 JS 别离负责网页的内容出现(网页上须要显示哪些元素)和元素背地的行为逻辑,这种代码组织尽管层次结构十分清晰,但逻辑上却不够直观。React 将元素的出现代码(html)与其自身的逻辑代码(JS)先进行组合,从而形象出一个带有行为的逻辑的元素,即组件。这种代码组织形式更加合乎“所见即所得”的直观感触。此外,因为很多元素在大部分场景下对应的行为逻辑都是统一的,咱们 能够能够很容易地实现出标准化的 React 组件,在不同的场景下复用它们。
心愿上面的例子能够帮你对 React 的组件化有更具体的感触:
上面的两份代码均在页面上渲染了一个按钮,被点击后会在控制台记录按钮上显示的文本。
写法一. 应用 JS 和 html 将内容出现和元素逻辑离开
index.html
<!DOCTYPE html>
<html>
<body>
<div id="root">
<button id="btn">Click me</button>
<script src="index.js"></script> # 引入 js
</div>
</body>
</html>
index.js
let btn = document.getElementById("btn");
btn.addEventListener("click", function() {console.log(btn.innerText);
});
写法二. 应用 React 组件
react_index.html
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
</html>
react_index.js
function LogButton(props) {function LogText() {console.log(props.text);
}
return <button onClick={LogText}>{props.text}</button>;
}
ReactDOM.render(
<LogButton text="Hello world!" />,
document.getElementById('root')
);
写法二中的 react_index.js 中定义了一个函数组件 LogButton
,该函数接管一个参数 props,蕴含了组件须要的所有属性,并返回一个 html 元素。在该例中,LogButton
只有一个 .text
属性, 元素自带的逻辑 LogText
即被点击后将按钮上的显示文本写入控制台日志。
除函数组件外,React 还反对类组件,能够参阅 React 的官网文档
Props 与 State
上一节提到,React 的组件接管一个参数 props,该参数蕴含了组件所须要的所有属性。须要特地留神的是,Props 是只读的,即 React 组件决不能批改本身的 Props。但在很多场景下,咱们须要动静的 UI,React 提供的 state 来反对这种需要。
上面的例子实现了一个计时器,在按下计时按钮后,显示曾经过的秒数:
import React, {useState, useEffect, useRef} from "react";
function SecondsCounter() {const [text, setText] = useState("start");
const [timingState, setTimingState] = useState(false);
const [time, setTime] = useState(0);
const timer = useRef(0);
useEffect(() => {if (timingState) {
timer.current = setInterval(() => {setTime(t => t + 1)}, 1000
);
} else {clearInterval(timer.current);
}
}, [timingState]);
function clickHandle() {if (timingState) {setTimingState(false);
setText('start');
} else {setTimingState(true);
setText('pause')
}
}
return (
<div>
<button onClick={clickHandle}>{text}</button>
<p>{time} seconds had passed.</p>
</div>
);
}
ReactDOM.render(
<SecondsCounter />,
document.getElementById('root')
);
下面的例子会在页面上渲染出一个按钮和按秒为单位的计时后果,初始状态下,按钮上显示的内容为 start,点击按钮后,计时开始,按钮上显示的内容变为 pause,再次点击后,计时暂停,按钮上的本文变回 start。
这里从 React 库引入了 useState,useEffect,useRef 三个函数,这些以 use 结尾的函数被称为 HOOK,上面逐个介绍它们的用法:
useState
useState
能够定义一个组件可能扭转的 state,根本应用形式为:
const [state, setState] = useState(0);
useState
会返回一个数组,数组的第一个元素是一个 state 变量,第一个元素是用于设置该 state 变量的函数,它们的名称并不是 useState
API 的一部分,你能够取本人想要的名字。传入useState
的参数是该 state 变量的初始值,这里是 0,故该 state 是一个 number 类型的变量,当然你也能够定义其余类型的 state 变量,例如传递一个字符串给 useState 来获取一个字符串类型的 state,你甚至能够给 useState 对象来定义一个简单 state
const [complexState, setComplexState] = useState({name: "Tom", age: 18})
想要扭转 state 时,能够应用 useState
返回数组的第二个元素,但请留神,不要间接批改 state
const [state, setState] = useState(0);
setState(1); // 将 state 设置为 1
state = 2;// error!!!不能间接批改 state
state 可能是异步的
处于性能思考,react 并不会在 setState 调用后立即批改 state,而是将所有的 setState 进行合并后再执行,这可能导致一个令老手困惑的状况
const [state, setState] = useState(0);
setState(state + 1); // 此时 state 的值是 0
setState(state + 1); // 此时 state 的值仍是 0
在上述代码执行结束,渲染下一帧时,state 的值并不是 2 而是 1。但有时候咱们想要的可能不是这种成果,例如在下面的计时器例子中,咱们想要 time 每隔一秒就主动加 1,能够将一个函数传入 setState
const [time, setTime] = useState(0);
setTime(time => time + 1);
这里 time => time + 1
是一个简化的箭头函数,箭头函数是 ES6 规范新增的一种函数,箭头函数语法直观,定义匿名函数十分不便
例如,对于函数
function add(a, b) {return a + b;}
相应的箭头函数的写法
(a, b) => {return a + b;}
当箭头函数的返回体只有一条返回语句时,能够简写为
(a, b) => a + b;
更多无关箭头函数和 JS 的常识能够参阅 JavaScript 教程