你要尽全力保护你的梦想。那些嘲笑你梦想的人,因为他们必定会失败,他们想把你变成和他们一样的人。我坚信,只要我心中有梦想,我就会与众不同,你也是。 —— 《当幸福来敲门》
React
一些入门知识。用来让读者对 React
有一定的认识
图片来源
constructor()
render()
componentDidMount()
componentDidUpdate()
componentWillUnmount()
getSnapshotBeforeUpdate()
shouldComponentUpdate()
React
的生命周期一共有三个阶段,分别为 挂载阶段
、更新阶段
和 卸载阶段
constructor()
render()
componentDidMount()
Vue
的 mounted
)shouldComponentUpdate()
—— 强制更新 ( 使用 this.forceUpdate()
) 会跳过这个钩子render()
componentDidUpdate()
true
时会选择重绘props
变化重新获取数据componentWillUnmount()
Vue
的 beforeDestroy
)state
是 React
里面存储状态的对象,相当于 Vue
的 data
setState()
forceUpdate()
setState(updater, [callback])
setState
可接受两个参数,第二个是可选的。
使用 setState
设置 state
有两种方式
setState
传入对象或者函数对象,直接修改 state
中的数据setState
中传入两个函数。第一个函数有两个参数,第一个参数是当前的 state
,第二个参数是当前的 props
,返回的是要修改的state
对象,类似于第一种设置方式;第二个函数是更新后的回调函数。官方建议用 componentDidUpdate()
代替更新后的回调函数,其中一个原因是 React
为了考虑最佳性能,会在所有 setState
全部执行完之后进行统一的渲染。
如果你同时使用了两次 setState
修改同一个 state
值,会存在一些隐患。看下面这个例子
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
value: 0 };
}
componentDidUpdate(prevProps, prevState) {
console.log('componentDidUpdate: ' + this.state.value);
}
onClick = () => {
this.setState(
{
value: 4 },
() => console.log('onClick: ' + this.state.value));
this.setState(
{
value: 8 },
() => console.log('onClick: ' + this.state.value));
}
render() {
return <button onClick={
this.onClick}>{
this.state.value}</button>;
}
}
这样的代码将会打印两次 onClick: 8
。因为这两个 setState
是同时处理的。
component.forceUpdate(callback) // 强制渲染组件
默认情况下,当组件的
state
或props
发生变化时,组件将重新渲染。如果render()
方法依赖于其他数据,则可以调用forceUpdate()
强制让组件重新渲染。
React
使用 虚拟DOM
的方式优化性能。
当React
组件的状态发生变化时,React
不会直接更新视图,而是创建一个新的虚拟DOM
缓存所有发生变化的状态,然后等到合适的时候 一次性 更新到浏览器。
当React
组件重新渲染时,React
不会渲染整个视图,而是使用 Diff
算法 比较新旧虚拟DOM
之间的差异,然后只把 真正发生变化的地方 更新到浏览器。
DOM
结构是相对稳定的key
属性是用来帮助 React
识别那些元素改变了,从而更好的使用虚拟DOM
提高性能,所以它最好是唯一的。
无状态组件又叫 纯函数组件 ,是没有 state
的组件,通常用来定义可复用的模板。
以下是一个例子。
const Component = (props) = (
<div>{
props.xxx}</div>
);
类组件又称有状态组件,它是有 state
的,通常用来定义交互逻辑和业务数据。
以下是一个例子
class Home extends React.Component {
constructor(props) {
super(props);
};
render() {
return (
<Header/>
)
}
}
高阶组件(HOC)是
React
中用于复用组件逻辑的一种高级技巧。HOC 自身不是React API
的一部分,它是一种基于React
的组合特性而形成的设计模式。
具体而言,高阶组件是参数为组件,返回值为新组件的函数。
HOC
是用来将一个组件转换为另外一个组件的。
Context
设计目的是为了共享那些对于一个组件树而言是“全局”的数据。可以把 Context
理解为注入数据的工具(类似于 Vue
的 provider
) 。
Context
提供了一个无需为每层组件手动添加props
,就能在组件树间进行数据传递的方法。
我们通常在需要修改某个全局类型时使用 Context
,例如我们需要实现 换肤 效果。
点击我!我是传送到官网的入口
// Context 可以让我们无须明确地传遍每一个组件,就能将值深入传递进组件树。
// 为当前的 theme 创建一个 context(“light”为默认值)。
const ThemeContext = React.createContext('light');
class App extends React.Component {
render() {
// 使用一个 Provider 来将当前的 theme 传递给以下的组件树。
// 无论多深,任何组件都能读取这个值。
// 在这个例子中,我们将 “dark” 作为当前的值传递下去。
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
}
// 中间的组件再也不必指明往下传递 theme 了。
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
class ThemedButton extends React.Component {
// 指定 contextType 读取当前的 theme context。
// React 会往上找到最近的 theme Provider,然后使用它的值。
// 在这个例子中,当前的 theme 值为 “dark”。
static contextType = ThemeContext;
render() {
return <Button theme={
this.context} />;
}
}
React
一些主流的开发技巧。
Hook
是React 16.8
的新增特性。它可以让你在不编写class
的情况下使用state
以及其他的React
特性。
Hook
是 React16.8
之后主流的开发利器。Hook
主要实现于函数组件或者自定义的Hook
函数。
我们通常使用 useState
来设置 state
const [state, setState] = useState(initialState);
以下使用 useState
的例子
const [loading, setLoading] = useState(false);
useState
返回一个数组,数组的第一个成员是 state
状态,第二个成员是设置 state
状态的函数。
useEffect(callback,[count])
useEffect
做了什么? 通过使用这个Hook
,你可以告诉React
组件需要在渲染后执行某些操作。React
会保存你传递的函数(我们将它称之为 “effect”),并且在执行DOM
更新之后调用它。
这个 hook
主要是用来操作副作用的。它跟 class 组件中的 componentDidMount()
、componentDidUpdate()
和 componentWillUnmount()
具有相同的用途。
useEffect()
有两个参数,第一个参数( 是个函数 )是用来操作副作用的,第二个参数( 是个数组、可选 )是用来约束在哪些数据更新时需要执行。
参数情况 | 效果 | 注意事项 |
---|---|---|
不传 | 每次渲染后都执行清理或者执行effect | 这可能会导致性能问题,比如两次渲染的数据完全一样 |
传递空数组 | 只运行一次的 effect(仅在组件挂载和卸载时执行) | 这就告诉 React 你的 effect 不依赖于 props 或 state 中的任何值,所以它永远都不需要重复执行 |
传递 [ count ] | React 将对前一次渲染的count和后一次渲染的count进行比较。若相等React 会跳过这个 effect, | 实现了性能的优化 |
参考文献
如果给第二个参数传递指定的值,可以实现一定的性能优化。具体根据实际情况来选择。它( 第二个参数 )可以控制setEffect
的执行频率。
副作用指的是在完成某件事时附带执行的事。在 useEffect
的基本概念中,主要的事是 DOM
构建,其余的就是副作用。
const value = useContext(MyContext);
接收一个
context
对象(React.createContext
的返回值)并返回该context
的当前值。当前的context
值由上层组件中距离当前组件最近的的
value
prop
决定。
通常分两步实现使用 context
const ThemeContext = React.createContext(themes.light);
const theme = useContext(ThemeContext);
点击我!我是传送到官网的入口
const themes = {
light: {
foreground: "#000000",
background: "#eeeeee"
},
dark: {
foreground: "#ffffff",
background: "#222222"
}
};
const ThemeContext = React.createContext(themes.light);
function App() {
return (
<ThemeContext.Provider value={
themes.dark}>
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar(props) {
return (
<div>
<ThemedButton />
</div>
);
}
function ThemedButton() {
const theme = useContext(ThemeContext);
// 会得到color: "#ffffff";background: "#222222";
return (
<button style={
{
background: theme.background, color: theme.foreground }}>
I am styled by theme context!
</button>
);
}
持续学习,永不放弃( 持续更新中… )。