拥抱react hooks!

703 阅读3分钟

一、前言

本文不详细描述react hooks 语法,语法概念网上太多了,单纯介绍react hooks出现的目的、优点和使用中常见的问题。

1.1 React Hook是什么?

创建传统react组件的三种方式:

// 1.Function Component(无状态函数式组件)
const Test = (props) => (
  <div>Hello, {props.name}</div>
)

// 2.ES6 class component
class Test extends React.Component {
  render() {
    return (
      <div>Hello, {this.props.name}</div>
    )
  }
}

// 3.ES5 React.createClass
React.createClass({
    propTypes: {
        name: React.PropTypes.string
    },
    render: function() {
      return (
          <div>Hello, {this.props.name}</div>
      )
    }
})

React.createClass 和 ES6 class component创建组件每次调用都会创建一个实例(生命周期、state维护等),而Function Component没有生命周期和state维护避免了不必要的内存分配和检查。Function Component的问题就在于它没有生命周期和state。React Hook(React 16.8 的新增特性)的出现正式为了解决Function Component没有生命周期和state的问题。

总结:React Hook就是在 Function Component开了一些hook,使Function Component 拥有自己的 state 和 生命周期,所以React Hook的新语法只能在Function Component中使用,否则react将抛出错误:React Hooks Error: Hooks can only be called inside the body of a function component;

1.2 React Hook的优点?

先上代码,一个简单的获取分页数据组件(具体引用文件不展示,大概看下结构)

// 传统组件
class Test extends React.Component {
  state = {
    data: [],
    page:1
  }

  async fetchGetListData() {
  	const {page} = this.state;
  	const data = await getListData({page});
    this.setState({data});
  }
  
  pageChangeHandle(pageNum) {
  	this.setState({ page: pageNum }, this.fetchGetListData)
  }
  
  componentDidMount() {
    this.fetchListData(this.setState);
  }

  render() {
  	const { data, page } = this.state;
    return (
      <div>
      	<List data={data}>
        <button onClick={() => {this.pageChangeHandle(page + 1)}>下一页</button>
      </div>
    )
  }
}

// Hooks
const Test:FC = ():ReactElement => {

	const [data, setData] = useState<any[]>([]);
    
    const [page, setPage] = useState<number>(1);
    
    async fetchGetListData() {
  	  const data: any[] = await getListData({page});
      setData(data);
    }
    
    useEffect(() => {
      fetchGetListData();
    }, [page])

	return (
      <div>
      	<List data={data}>
        <button onClick={() => {setPage(page + 1)}>下一页</button>
      </div>
    )
}

1.useEffect替代componentWillMount、componentDidUpdate、componentWillRecieveProps、componentWillUnmount(useEffect可以返回一个函数,函数就相当于componentWillUnmount),告别繁琐的生命周期,可专心实现业务代码,不用被生命周期所束缚。

2.useState替代state,告别class组件this,告别烦人的bind(this)。

3.清爽的代码风格,代码阅读性增强。

4.代码量更少,更容易复用代码。

5.未来react团队重点优化方向。

1.3 React Hook使用总结(遇到的坑传给大家)?

1.将完全不相关的 state 拆分为多组 state

  // 错误的
  const [state, setState] = useState({
  	page: 1,
    data: []
  });
 // 正确的(page和data本身就没有关联性,它们是独立的两个属性)
  const [data, setData] = useState<any[]>([]);
  
  const [page, setPage] = useState(1);

2.如果某些 state 是相互关联的,或者需要一起发生改变,就可以把它们合并为一组 state。

// 错误的
  const [name, setName] = useState('');
  const [sex, setSex] = useState('男');
// 正确的(name和sex都是表单数据他们具有关联性)
  const [params, setParams] = useState({
  	name: '',
    sex: '男'
  })

3.依赖数组依赖的值最好不要超过 3 个,否则会导致代码会难以维护。

// 错误的
useEffect(() => {
  console.log(123)
}, [a, b, c, d, e, f]);

// 正确的
useEffect(() => {
  console.log(123)
}, [a, b, c]);

useEffect(() => {
  console.log(123)
}, [d, e, f]);

总结

react hooks是react官方未来的方向,在考虑项目技术更新或者学习时,从业者无从选择只能顺应趋势。react hook的出现确实让人眼前一亮,以前繁杂的代码用了react hook后会有一种小清新,并且享受写代码的过程。或许这就是它的魅力吧!

个人技术博客已经使用typescript + react hooks + antd 重构完成,有兴趣学习的小伙伴可以看看!

个人博客地址,有兴趣的可以看一看

博客网站有对应的github地址哦!!!