hooks api 详细demo

2023-11-13

本文所有代码demo:https://stackblitz.com/edit/react-hooks-memo-gwv9c6?file=index.js

overview

How do React hooks really work? -- hooks closures

原文地址:https://www.netlify.com/blog/2019/03/11/deep-dive-how-do-react-hooks-really-work/
setCount 返回一个函数 函数可以访问useState 内部的变量 => 闭包

const [count, setCount] = useState(0);
复制代码
// simple useState useEffect  demo
const MyReact = (function() {
  let hooks = [],
    currentHook = 0 // array of hooks, and an iterator!
  return {
    render(Component) {
      const Comp = Component() // run effects
      Comp.render()
      currentHook = 0 // reset for next render
      return Comp
    },
    useEffect(callback, depArray) {
      const hasNoDeps = !depArray
      const deps = hooks[currentHook] // type: array | undefined
      const hasChangedDeps = deps ? !depArray.every((el, i) => el === deps[i]) : true
      if (hasNoDeps || hasChangedDeps) {
        callback()
        hooks[currentHook] = depArray
      }
      currentHook++ // done with this hook
    },
    useState(initialValue) {
      hooks[currentHook] = hooks[currentHook] || initialValue // type: any
      const setStateHookIndex = currentHook ; // for setState closure
      const setState = newState => (hooks[setStateHookIndex] = newState)
      return [hooks[currentHook++], setState]
    }
  }
})()
复制代码
// in usage
function Counter() {
  const [count, setCount] = MyReact.useState(0)
  const [text, setText] = MyReact.useState('foo') // 2nd state hook!
  MyReact.useEffect(() => {
    console.log('effect', count, text)
  }, [count, text])
  return {
    click: () => setCount(count + 1),
    type: txt => setText(txt),
    noop: () => setCount(count),
    render: () => console.log('render', { count, text })
  }
}
let App
App = MyReact.render(Counter)
// effect 0 foo
// render {count: 0, text: 'foo'}
App.click()
App = MyReact.render(Counter)
// effect 1 foo
// render {count: 1, text: 'foo'}
App.type('bar')
App = MyReact.render(Counter)
// effect 1 bar
// render {count: 1, text: 'bar'}
App.noop()
App = MyReact.render(Counter)
// // no effect run
// render {count: 1, text: 'bar'}
App.click()
App = MyReact.render(Counter)
// effect 2 bar
// render {count: 2, text: 'bar'}
复制代码

useState

import React, { useState} from 'react';
import { render } from 'react-dom';
export default function App() {
  const [state, setState] = useState({});
  const onClick = () => setState({click:!state.click});
  return (
    <div>
      <p>You clicked count {count} times</p>
      <button onClick={onClick}>
        Click me count
      </button>
    </div>
  );
};
复制代码
Tip

模拟class setState
You don’t have to use many state variables. State variables can hold objects and arrays just fine, so you can still group related data together. However, unlike this.setState in a class, updating a state variable always replaces it instead of merging it。
我们可以在声明state的时候,使用数组或者对象。class里的setState是合并state,hooks里的setState是替换state。

useEffect

  • React 会记录下你传给 useEffect 的这个方法,然后在进行了 DOM 更新之后调用这个方法。
  • Hooks 使用了 JavaScript 的闭包(closures)。将 useEffect 放在一个组件内部,可以让我们在 effect 中,即可获得对 count state(或其它 props)的访问。
  • useEffect 在每次 render 之后都会调用。useEffect第二个参数是一个inputs数组。 他会在每次render之前比较依赖的inputs里的每一项。如果改变才会调用useEffect。这里类似 componentDidUpdate
不需要清理的 effects

使用场景:网络请求,手动更新 DOM,打印日志

import { useState, useEffect } from 'react';

function Example() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  return (
    <div>
      <p>You clicked {count} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>
    </div>
  );
}
复制代码
需要清理的 effects
import { useState, useEffect } from 'react';

function FriendStatus(props) {
  const [isOnline, setIsOnline] = useState(null);

  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }

  useEffect(() => {
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    // 明确在这个 effect 之后如何清理它
    return function cleanup() {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
  });

  if (isOnline === null) {
    return 'Loading...';
  }
  return isOnline ? 'Online' : 'Offline';
}
复制代码
模拟生命周期 componentDidMount、componentDidUpdate 和 componentWillUnmount

import React, { useState,  useEffect } from 'react';
import { render } from 'react-dom';

export default function App() {
  
  const [count, setCount] = useState(0);
  const [count2, setCount2] = useState(0);

  useEffect(() => {
    console.log('similar componentDidmount count')
    document.title = `You clicked count ${count} times`;
  },[]);

  useEffect(() => {
  //  Optimizing Performance by Skipping Effects
    console.log('similar componentDidmount/componentDidUpdate count2')
    document.title = `You clicked count2 ${count2} times`;
  },[count2]);

  useEffect(() => {
    return ()=>{
      console.log('similar componentWillUnmount')
    }
  });

  return (
    <div>
      <p>You clicked count {count} times</p>
      <p>You clicked count2 {count2} times</p>
      <button onClick={() => setCount(count + 1)}>
        Click me count
      </button>
      <button onClick={() => setCount2(count2 + 1)}>
        Click me count2
      </button>
    </div>
  );
}
复制代码
Tip

如果你熟悉 class 组件中的生命周期方法,你可以把 useEffect Hooks 视作 componentDidMount、componentDidUpdate 和 componentWillUnmount 的结合。
如果你只想运行一次effect 并清楚它, (componentDidMount and componentDidUpdate),你可以在第二个参数里传一个空数组。但是react官方建议不要将这成为习惯,因为这样会引起bug(可以参考 => 需要清理的 effects)。

useContext

//  子组件 调用
import React, { useState, useEffect,useContext } from 'react';
import { render } from 'react-dom';
import DataContext from './dataContext';
export default function App() {
  const data = useContext(DataContext);
  console.log(data) // {foo: "ProviderValue"};
  const [state, setState] = useState({});
  const onClick = () => setState({click:!state.click});
  return (
    <div>
      <button onClick={onClick}>
        Click me  
      </button>
      <DataContext.Consumer>
        {
          value => <div>{value.foo}</div> 
          //  value  {foo: "ProviderValue"}
        }
      </DataContext.Consumer>
    </div>
  );
};
//  父组件 提供
    <p>
        <DataContext.Provider value={ProviderValue}>
          <Context />
        </DataContext.Provider>
    </p>
//  提供数据
import React  from 'react';
const DataContext = React.createContext({});
export default DataContext;

复制代码
Tip

useContext 不用再写嵌套的 Consumer 组件 回调函数 可以直接获取context的值
useContext 接收一个 由React.createContext创建的返回值 并返回当前 context 的value 。获取的是最近的 provider 提供的context。每当provider提供的context更新时,useContext会最后一次context value触发render

useCallback && useMemo

useCallback
const memoizedCallback = useCallback(
()=>{
    doSomething(a,b)
},
[a,b]);
复制代码

返回一个 被记忆的(Memoized) 回调函数 接收一个回调函数和一个数组,useCallback 会返回一个 被记忆的回调函数,这个函数只有在 数组里的其中一个值变化的时候才变化。用于优化子组件,防止不必要的渲染的时候。类似于shouldComponentUpdate。

useCallback(fn, inputs) 等价于 useMemo(() => fn, inputs)
数组里的输入并不是被当作参数传给后面的回调函数。确切的说:每一个在回调函数里被引用的值也应该出现在后面的数组里。

useMemo
const memoizedValue = useMemo(()=> computedExpensiveValue(a,b),[a,b]);
复制代码

返回一个 被记忆的(Memoized)值 useMemo 只有在输入的数组里的其中一个值改变的时候会重新计算被记忆的值。 这个优化的方法可以在每次渲染的时候避免昂贵的计算。

Tip

在React.Component里,如果props/state发生改变就会触发重新渲染(re-render),当父组件(parent components)重新渲染也会重新渲染 子组件(child components)。 在class Component里 ,shouldComponentUpdate 指定props改变更新components或使用 React.PureComponent。
请看下面的demo

const ChildComponent = React.memo(({ onClick, children }) => {
  console.log('clicked!')
  return <button onClick={onClick}>{children}</button>
})
                                                                   
const ParentComponent = () => {
  const [state, setState] = useState({ children: [1, 2, 3] })
  const { children } = state
  const onClick = () => setState({ children, foo: 'baz' })
  return (
    <div>
      {
        children.map(child => (
          <ChildComponent key={child} onClick={onClick} >
            { child }
          </ChildComponent>
        )) 
      }
    </div>
  )
}

ReactDOM.render(<ParentComponent />, document.getElementById('app'))
复制代码

我们把button组件 用memo 记忆下来,在改变state的时候子组件不应该再次渲染。但实际上是,子组件被重新渲染里。 原因是:ParentComponent在重新渲染时,onClick被重新绑定一个新的尖头函数。在shallowEqual的strict equal情况下被判定是不相等造成memo失败。
改变一下 用useCallback就可以了

import React, { useState, useCallback, useMemo } from 'react';
import { render } from 'react-dom';


const ChildComponent = React.memo(({ onClick, children }) => {
  console.log('callback clicked!')
  return <button onClick={onClick}>{children}</button>
});
                                                                   
const ParentComponent = () => {
  const [state, setState] = useState({ children: [1, 2, 3] })
  const { children } = state
  const onClick = useCallback (
    ()=>setState({ children, foo: 'baz' }),
  [children]);
  return (
    <div> 
    <h1>callback demo</h1>
      {
        children.map(child => (
          <ChildComponent key={child} onClick={onClick} >
            { child }
          </ChildComponent>
        )) 
      }
    </div>
  )
}

render(<ParentComponent />, document.getElementById('callback'));
复制代码

原因:在 class component中,我们可以作为props传递下去的callback是在class component的原型链上,是 member function。但是 function component是不存在instance,所以不能绑定callback。这就是useCallback/useMemo 的使用。在function component中 中产生一个不随父组件重新渲染而改动(mutate)的 callback。

//  useCallback包裹的cb和未被包裹的cb对比
import React, { useState, useCallback, useMemo } from 'react';
import { render } from 'react-dom';

const ParentComponent = () => {
  const [state, setState] = useState({ children: [1, 2, 3] });
  const { children } = state;
  //  点击changeState 会看到 memoizedCallback === unMemoizedonClick false
  const changeState = () => setState({ children, foo: 'baz' });
  const memoizedCallback = useCallback(changeState, []);
  const unMemoizedonClick = changeState;
  return (
    <div>
      <h1>callback demo</h1>
      <div>
        <div>
          <button onClick={changeState}> changeState </button>
        </div>
        unMemoizedonClick === memoizedCallback: {String(unMemoizedonClick === memoizedCallback)}
      </div>
    </div>
  )
}

render(<ParentComponent />, document.getElementById('memoizedCallback&&unMemoizedonClick'));
复制代码
//  只有在dep变化时候 回调函数才会被调用
import React, {
  useEffect,
  useMemo,
  memo,
  useState,
  Fragment,
  useCallback
} from "react";
import ReactDOM from "react-dom";

import "antd/dist/antd.css";
import "./index.css";

const App = () => {
  const [state, setState] = useState({
    recieptVisible: 1,
    invoinceVisible: 1,
    noticeVisible: false,
    selectedRows: []
  });
  const { recieptVisible, invoinceVisible } = state;
  const cbfunc = () => {
    return setState({
      ...state,
      recieptVisible: recieptVisible + 1
    });
  };



  //  计算属性 get useMemo
  //  例如 算数的分子变化时候 结果变化 要进行大量计算的时候使用
  //  有点像 vue的 计算属性
  const memofunc = () => {
    return recieptVisible + invoinceVisible;
  };

  //  watch useCallback
  //  例如 modal的visible变化的时候  调用cb
  const Cb = useCallback(cbfunc, [recieptVisible]);
  const memoCb = useMemo(memofunc, [recieptVisible]);

  return (
    <div>
      <div>{recieptVisible}</div>

      <div>{memoCb}</div>
      <button
        type="primary"
        onClick={() =>
          setState({ ...state, recieptVisible: recieptVisible + 1 })
        }
      >
        Open recieptVisible
      </button>

      <button type="primary" onClick={Cb}>
        Cb
      </button>

      <div>{invoinceVisible}</div>
      <button
        type="primary"
        onClick={() =>
          setState({ ...state, invoinceVisible: invoinceVisible + 1 })
        }
      >
        Open invoinceVisible
      </button>
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("container"));

复制代码

useRef

const refContainer = useRef(initialValue);
复制代码

如果有initialValue 返回 初始化时候 {current:initialValue}
组件render之后 返回 所指 当前 组件实例 {current:el}


import React, { useRef } from 'react';
import { render } from 'react-dom';

export default function App() { 
  const inputEl = useRef(null);
 const onButtonClick = () => {
    console.log(inputEl,'inputEl') // {current:el}
  };
  return (
    <>
      <input ref={inputEl} type='text' />
      <button onClick={onButtonClick}>button</button> 
    </>
  );
}
复制代码
Tip

原来 ref = {(node) => this.el = node} 把node放在回调函数里取出来更直接

useImperativeHandle

useLayoutEffect

如果要进行dom操作,配合ref就应该使用useLayoutEffect ,他会阻塞页面渲染。

tip

在一些不常见的情况下你也许需要他们同步调用(比如计算元素尺寸),我们提供了一个单独的 useLayoutEffect 来达成这样的效果。它的 API 和 useEffect 是相同的

useDebugValue

参考

转载于:https://juejin.im/post/5cb6d0356fb9a06888415962

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

hooks api 详细demo 的相关文章

  • 在 Angular 中使用 Vue 组件

    我有一个用 Vue 构建的项目 我想在 Angular 应用程序中重用 Vue 应用程序中的组件 这样我就不必从头开始重建每个组件 我在medium上看到了这个教程 如何在 Angular 应用程序中使用 Vue 2 0 组件 https
  • 禁用内容安全策略

    当我开发网站时 我经常想看看特定功能在网站上的外观如何 所以我会使用 chrome 开发者工具并经常运行一些 javascript 脚本 我经常发现一些脚本由于内容安全策略 CSP 而无法运行的问题 我完全理解该策略是为了防止跨站点脚本攻击
  • 我如何在 AngularJS 中监听点击并按住的情况?

    我制作了一个时间计数器 您可以通过单击按钮来增加或减少时间 然而 我希望当我单击并按住按钮时 时间的价值会不断攀升 所以目前如果你看到我的Plunkr http plnkr co edit BxX9x5zYFMXVqt5JsN1F p pr
  • Oo 任何 IDE 中的 javascript 代码补全

    你知道有什么IDE可以自动完成这种代码吗 我这里有一个 javascript 类生成器 function var core bind function method scope if method instanceof Function t
  • 访问sendBeacon发送的数据

    文档表明sendBeacon通过发送其数据HTTP POST request 但在 PHP 中 POST变量似乎是一个空数组 这是我的 JavaScript 代码 navigator sendBeacon beacon log php My
  • 用隐藏单元格补充 colspanned 表格有什么不好吗?

    我一直在表格上开发一些排序和选择功能 我发现在具有跨单元格的表格中定位非常困难 我只是添加了跨区单元格并将其隐藏 它看起来不错 它与我的 js 一起工作 非常适合索引 但我想知道这是否是合法的方法 stuffing display none
  • 在Javascript中按降序对字符串进行排序(最有效)?

    W3Schools 有这个例子 var fruits Banana Orange Apple Mango fruits sort fruits reverse 这是在 Javascript 中按降序对字符串进行排序的最有效方法吗 Updat
  • 使用 CryptoJS 更改密钥 [重复]

    这个问题在这里已经有答案了 我正在使用 CryptoJS 来加密和解密文本 在这里 我只是获取消息并显示加密和解密消息 我使用DES算法进行加密和解密 这是我的 HTML 文件
  • Javascript - 将值从下拉框传递到 Google Maps API

    我正在使用 Google 地图 API 为一家出租车公司创建报价表 目前 用户在 2 个文本框中输入出发点和接载点 API 会计算两点之间的距离以及行程费用 我正在尝试添加两个具有设定位置的下拉框 以便用户可以选择这些位置之一或使用文本框输
  • 是否有任何非轮询方式来检测 DOM 元素的大小或位置何时发生变化?

    很长一段时间以来 我一直在寻找一种方法来检测 DOM 元素的大小或位置何时发生变化 这可能是因为窗口调整了大小 或者因为向该元素添加了新的子元素 或者因为在该元素周围添加了新元素 或者因为 CSS 规则已更改 或者因为用户更改了浏览器的字体
  • 如何在 Angular 中从父组件访问子组件?

    I have mat paginator在子组件a中 如下所示 子组件 html
  • Typeahead.js substringMatcher 函数说明

    我只是在做一些研究Typeahead js这是一个非常酷的图书馆 感谢文档 我已经成功地获得了一个基本的示例 该文档也非常好 但是我试图弄清楚以下代码块实际上在做什么 var substringMatcher function strs r
  • 将数组排序为第一个最小值、第一个最大值、第二个最小值、第二个最大值等

    编写一个JS程序 返回一个数组 其中第一个元素是第一个最小值 第二个元素是第一个最大值 依此类推 该程序包含一个函数 该函数接受一个参数 一个数组 该函数根据要求返回数组 输入示例 array 2 4 7 1 3 8 9 预期输出 1 9
  • 淡出和循环一组 div 的最佳方式

    假设我有以下 div div class a You are funny div div class b You are smart div div class c You are cool div 最好的展示方式是什么div a持续 5
  • Chartjs刻度标签位置

    尝试让 Y 轴刻度标签看起来像image https i stack imgur com XgoxX png 位于秤顶部且不旋转 缩放选项当前如下所示 scales yAxes id temp scaleLabel display true
  • JavaScript 代码在不使用 ActiveX 的情况下截取网站屏幕截图

    我有一个用户与之交互的 JavaScript 应用程序 我需要保存当前界面的外观 裁剪出我需要的部分 或者通过指定div只拍摄我需要的部分 然后发送回服务器 显然任何外部服务都无法做到这一点 我需要一个 JavaScript 或Flash
  • 数据表日期范围过滤器

    如何添加日期范围过滤器 like From To 我开始进行常规搜索和分页等工作 但我不知道如何制作日期范围过滤器 我正在使用数据表 1 10 11 版本 My code var oTable function callFilesTable
  • 如何在 javascript 正则表达式中匹配平衡分隔符?

    我原以为这个问题是不可能的 据我所知 Javascript 的正则表达式既没有递归插值 也没有漂亮的 NET 平衡组功能 但问题就在那里 如问题 12 所示正则表达式 alf nu http regex alf nu 匹配平衡对 lt an
  • 需要有关 React Js 的帮助

    我是 React Js 新手 我的代码无法正常工作 请看下面 这是我的脚本文件Main jsx 该文件由 React 编译 输出放置在 dist 文件夹下的 main js 文件中 var react require react react
  • 用于 C# XNA 的 Javascript(或类似)游戏脚本

    最近我准备用 XNA C 开发另一个游戏 上次我在 XNA C 中开发游戏时 遇到了必须向游戏中添加地图和可自定义数据的问题 每次我想添加新内容或更改游戏角色的某些值或其他内容时 我都必须重建整个游戏或其他内容 这可能需要相当长的时间 有没

随机推荐

  • 【缓存】缓存,这么用才真正达到缓存的效果

    1 概述 转载 https zhuanlan zhihu com p 62508629 一 什么是缓存 平常的开发项目中 多多少少都会使用到缓存 因为一些数据我们没有必要每次查询的时候都去查询到数据库 一个形象的比喻 数据库是人的身体 缓存
  • 序列比对算法-计算生物学

    1 序列比对指将两个或多个序列排列在一起 标明其相似之处 序列中可以插入间隔 通常用短横线 表示 对应的相同或相似的符号 在核酸中是A T 或U C G 在蛋白质中是氨基酸残基的单字母表示 排列在同一列上 这一方法常用于研究由共同祖先进化而
  • CSS 3D转换——transform 属性的 rotatex() 方法和 rotatey() 方法

    目录 CSS 3D转换 浏览器支持 转换属性 3D Transform方法 常用方法 rotatex 方法 rotatey 方法 结语 CSS 3D转换 CSS3 允许我们使用 3D 转换来对元素进行格式化 浏览器支持 表格中的数字表示支持
  • 无线局域网下的远程控制、文件传输以及代理设置[Windows

    需求 在同一个路由器连接的局域网下 Ubuntu通过Windows端上网 Windows端远程控制Ubuntu系统 主机 Windows10 被操控端 Ubuntu18 04 在Windows方下载一个客户端 如Termius 远程控制和操
  • sql注入(报错注入)适用于union无法使用的情况

    extractvalue函数原理 这是一个对xml文件进行查询的函数 它的作用是 会从目标xml文件中返回所包含查询值的字符串 标准语法为 extractvalue XML document Xpath string extractvalu
  • for循环实现1-100之间偶数和

    package com itheima 04 需求 求出1 100之间偶数和 分析 A 定义求和变量 初始化值是0 B 获取1 100之间的数据 用for循环实现 C 把获取到的数据进行判断 看是否是偶数 如果是 就累加 D 输出求和结果
  • kernel:关于linux内核重要文件的基本描述

    linux Makefile 文件 这个Makefile文件的主要作用是指示make程序最终使用独立编译连接成的tools 目录中的build执行程序将所有内核编译代码连接和合并成一个可运行的内核映像文件 image 具体是对 boot 中
  • 协处理器cp15

    CP15访问CP15寄存器的指令 在基于ARM的嵌入式应用系统中 存储系统通常是通过系统控制协处理器CP15完成的 ARM处理器使用协处理器CP15的寄存器来控制cache 极高速缓存 TCM 高速缓存 和存储管理 CP15包含16个32位
  • anaconda的安装和常用指令

    1 下载anaconda之后 首先打开anaconda prompt 输入 conda version获取当前anaconda的版本 有可能会出现 首先要清理所有的包 conda clean packages tarballs 可以Win
  • 如何控制Spring bean的生命周期

    先了解下Spring bean的生命周期 创建 初始化 销毁 这对读懂Spring源码十分有帮助 控制Spring bean的生命周期有3种方式 下面分别用代码展示 方式一 Bean 注解上手动指定bean的初始化方法和销毁方法 Confi
  • 操作系统 存储管理 分页分段

    操作系统 存储管理 分页分段 分页存储管理 是将一个进程的逻辑地址空间分成若干个大小相等的片 称为页面或页 并为各页进行编号 从0开始 分页地址中的地址结构如下 页表实现了从页号到物理块号的地址映像 通过查找该表 即可找到每页在内存中的物理
  • c语言在线翻译器,【C语言】【window】--在线翻译器.doc

    C语言 Windows 在线翻译器 01 程序简介 程序名称 编译器 vs2010 其它也可以 程序大小 10K 文件包括 exe skinh she SkinH dll msvcr100 dll 程序界面 02 任务说明 光影队 任务 L
  • 自定义JSP中的Taglib标签之四自定义标签中的Function函数

    Java代码如下 自定义JSP中的Taglib标签之四自定义标签中的Function函数 package org lxh taglib import java util List public class FunctionTag publi
  • 报错"your evaluation license has expired, pycharm will now exit"

    1 修改C Windows System32 drivers etc hosts文件 将 0 0 0 0 account jetbrains com 添加到hosts文件的最后一行2 访问 http idea lanyus com 获取注册
  • NIO下载超大文件(支持20个G)

    服务端 nio将文件流写入response author zhanghp2017he foxmail com date 2022 8 22 param response return void exception RequestMappin
  • 【LeetCode75】第二十九题 删除链表的中间节点

    目录 题目 示例 分析 代码 题目 示例 分析 给我们一个链表 让我们把链表中间的节点删了 那么最直观最基础的办法是遍历两边链表 第一遍拿到链表长度 第二次把链表中间节点删了 这个暴力做法我没事过 不过貌似是可以解决问题的 所以我觉得这题的
  • React-router 5.0 利用高阶函数实现路由嵌套(web)

    如今 react router 已经升级到v5 0版本 v4 0版本做了较大的改革 代码中依然使用v3 0版本的写法 于是准备整改为v4 0以上版本 遇到了很多坑 于是做个笔记 首先 对比一下 v3 0 和 v4 0 版本 v4 0提供了r
  • librdkafka consumer封装的一点总结

    关于librdkafka producer可以看这里 consumer相较于producer需要注意的问题就少得多了 首先是初始化 string errstr unique ptr
  • 移植3- uboot之nandflash驱动移植

    2014 8 18 在上一篇文章中 我们已经将uboot启动起来了 但是如何将uboot spl搞到nandflash中去 这样可以拨动拨码开关选择nandflash启动 就可以从nandflash启动了呢 因此需要在uboot中实现nan
  • hooks api 详细demo

    本文所有代码demo https stackblitz com edit react hooks memo gwv9c6 file index js overview deep div How do React hooks really w