项目中reacthook的迭代

Hooks是React v16.7.0-alpha中加入的新特性。

本文主要是使用教程,记录下本人在持续开发中的react项目中对之前的页面的迭代笔记和一些总结。如果不了解,可以先看下我看到末尾的相关链接,我也是看这些教程的。


react生命周期有componentDidMount,componentDidUpdate等生命周期,那么想用hooks来替换原先的class component,那么必然要找到替代这写生命周期的方法。
下面就是介绍个人觉得hooks最最最常用到的一个api
useEffect,该 Hook 接收一个包含命令式、且可能有副作用代码的函数。
在函数组件主体内(这里指在 React 渲染阶段)改变 DOM、添加订阅、设置定时器、记录日志以及执行其他包含副作用的操作都是不被允许的,因为这可能会产生莫名其妙的 bug 并破坏 UI 的一致性。
执行时间
默认情况下,effect 将在每轮渲染结束后执行,但你可以选择让它 在只有某些值改变的时候 才执行。
那么,开始讲解下是如何代替那些生命周期

componentDidMount

组件在被挂载了之后会被调用

// useEffect 写法
React.useEffect(() => {
    // do somthing
}, []);
componentDidUpdate

更新阶段,当组件的props改变了,或组件内部调用了setState或者forceUpdate发生,会发生多次

// useEffect 写法
React.useEffect(() => {
   // do somthing
}, [props, state]);

在第二个参数(arr),所指向的值的内存地址更换了,他就会执行。注意我说的是,内存地址。这里我有遇到自己写的一个坑,导致当时卡了很久。

React.useEffect(() => {
    // do somthing
}, [props.goodsListPage.current]);
// 换页
function handleTableChange({ current: pages }) {
  dispatch({
    type: 'goods/changGoodsPage',
    payload: {
      page: pages
    },
  });
}

changGoodsPage(state, { payload }) {
  const { page } = payload;
  const { goodsListPage } = state;
  goodsListPage.current = page;
  return {
    ...state,
    goodsListPage
  }
},

可以看出我实际是改变这个值,但是useEffect并没有执行,然后我更改了changGoodsPage函数的写法,将goodsListPage的值重新赋值,更改其的内存地址,这样就可以执行了。

componentWillUnmount

卸载阶段,当我们的组件被卸载或者销毁了

// useEffect 写法
React.useEffect(() => {
  return () => {
    // do somthing
  }
}, []);

因为实际项目中,我在写的时候,基本上没写过不传第二个参数的useEffect,所以就不介绍了。想学习就可以通过最下面的相关链接学习。

备注: 这里为什么被介绍useLayoutEffect(useEffect的同步api)?
因为我一是在项目中基本不用,二是因为文档中并不推荐一开始就使用这个。只有当useEffect出问题的时候再去尝试使用seLayoutEffect。

下面就开始介绍useState
基本使用方法

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

第一个参数是变量名,第二参数是函数方法去改变这个变量,useState里放的是这参数的默认值
这里有个小tip,也是我当时写的时候,犯的错误。

const [count, setCount] = useState(0);
const [obj] = useState({ count });

当你使用setCount函数改变count的值时,变量obj是不是更改,因为在useState在定义变量时,是用深拷贝的。所以你直接定义const obj = { count }就可以了,不需要使用useState来定义。
最后讲一下,我用hooks写组件,当这个组件被引入到ant Design的from组件时,遇到的一个警告,虽然只是一个警告,并不影响程序运行,但是还是很想解决下。

这个警告大致意思是因为hooks是function component没有refs,需要用forwardRef()创建组件的refs。

export default React.forwardRef((props, ref) => {
  return <UploadImg {...props} forwardedRef={ref} />;
});

直接贴代码吧,有想详细了解的朋友可以看相关链接。

总结

在项目将class component改成hooks版的function component,在内部打印执行的次数,可以看出渲染次数明显减少,而且代码量也大大减少。 这只是仅仅讲解了两个hooks的api,和我在实践犯的错误。后续若新的hooks的新的心得体会,在后续写上。



更新于05-19

tip1:如果需要获取dom的ref,可以useRef获取

function TestUseRef() {
const inputEl = React.useRef(null);
const onButtonClick = () => {
// 点击按钮会设置input获取焦点
inputEl.current.focus(); // 设置useRef返回对象的值
};
return (
<div>
<p>TestUseRef</p>
<div>
<input ref={inputEl} type="text" />
<Button onClick={onButtonClick}>input聚焦</Button>
</div>
</div>
)
}

tip2:如果你在一个function component需要维护一些复杂的state的业务逻辑,可以使用useReducer来维护业务逻辑。

相关链接

1。译React高级话题之Forwarding Refs
2。react文档hooks
3。React Hooks 实用指南
4。useEffect 完整指南
4。使用React Hooks复用复杂业务组件