React基础知识总结(经典好文)

你要尽全力保护你的梦想。那些嘲笑你梦想的人,因为他们必定会失败,他们想把你变成和他们一样的人。我坚信,只要我心中有梦想,我就会与众不同,你也是。 —— 《当幸福来敲门》

React基础知识总结(经典好文)_第1张图片

基础

React 一些入门知识。用来让读者对 React 有一定的认识


生命周期(React Version >= 16.4)

React基础知识总结(经典好文)_第2张图片

图片来源


生命周期钩子列表

  • constructor()
  • render()
  • componentDidMount()
  • componentDidUpdate()
  • componentWillUnmount()
  • getSnapshotBeforeUpdate()
  • shouldComponentUpdate()

React的生命周期一共有三个阶段,分别为 挂载阶段更新阶段卸载阶段


挂载阶段

  1. constructor()
  2. render()
  3. componentDidMount()
constructor()
  • 用于初始化内部状态
  • 唯一可以直接修改state的地方
componentDidMount()
  • 只执行一次
  • UI渲染完成后调用(类似于 Vuemounted
render()
  • 渲染视图
  • 必须存在的

更新阶段

  1. shouldComponentUpdate() —— 强制更新 ( 使用 this.forceUpdate() ) 会跳过这个钩子
  2. render()
  3. componentDidUpdate()
shouldComponentUpdate()
  • 决定虚拟DOM是否要重绘,当返回值为 true 时会选择重绘
  • 一般可以由PureComponent自动实现
  • 常用于性能优化
componentDidUpdate()
  • 每次UI更新时被调用
  • 典型场景:页面需要根据 props 变化重新获取数据

卸载阶段

  • componentWillUnmount()
componentWillUnmount()
  • 组件移除时调用 ( 类似于 VuebeforeDestroy
  • 常用于释放资源 ( 例如清除定时器 )

state状态相关方法

stateReact里面存储状态的对象,相当于 Vuedata

  • setState()
  • forceUpdate()

setState()

setState(updater, [callback])

setState 可接受两个参数,第二个是可选的。

使用 setState 设置 state 有两种方式

  1. setState 传入对象或者函数对象,直接修改 state 中的数据
  2. 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 是同时处理的。


forceUpdate()

component.forceUpdate(callback) // 强制渲染组件

默认情况下,当组件的 stateprops 发生变化时,组件将重新渲染。如果 render() 方法依赖于其他数据,则可以调用 forceUpdate() 强制让组件重新渲染。


虚拟DOM和key属性

React 使用 虚拟DOM 的方式优化性能。

React组件的状态发生变化时,React不会直接更新视图,而是创建一个新的虚拟DOM缓存所有发生变化的状态,然后等到合适的时候 一次性 更新到浏览器。

React组件重新渲染时,React不会渲染整个视图,而是使用 Diff 算法 比较新旧虚拟DOM 之间的差异,然后只把 真正发生变化的地方 更新到浏览器。

虚拟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(高阶组件)

高阶组件(HOC)是 React 中用于复用组件逻辑的一种高级技巧。HOC 自身不是 React API 的一部分,它是一种基于 React 的组合特性而形成的设计模式。
具体而言,高阶组件是参数为组件,返回值为新组件的函数。

HOC 是用来将一个组件转换为另外一个组件的。


Context

Context 设计目的是为了共享那些对于一个组件树而言是“全局”的数据。可以把 Context 理解为注入数据的工具(类似于 Vueprovider) 。

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

HookReact 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他的 React 特性。

HookReact16.8 之后主流的开发利器。Hook 主要实现于函数组件或者自定义的Hook函数。


useState()

我们通常使用 useState 来设置 state

const [state, setState] = useState(initialState);

以下使用 useState 的例子

const [loading, setLoading] = useState(false);

useState 返回一个数组,数组的第一个成员是 state 状态,第二个成员是设置 state 状态的函数。


useEffect()

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 构建,其余的就是副作用。


useContext()

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>
  );
}

尾声

持续学习,永不放弃( 持续更新中… )。

React基础知识总结(经典好文)_第3张图片

你可能感兴趣的:(React,react)