温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

react hooks的示例分析

发布时间:2021-09-10 14:11:50 来源:亿速云 阅读:155 作者:小新 栏目:web开发

这篇文章将为大家详细讲解有关react hooks的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

React在16.8版本正式发布了Hooks。关注了很久,最近正好有一个小需求,赶紧来试一下。

需求描述

需求很简单,部门内部的一个数据查询小工具。大致长成下面这样:

react hooks的示例分析

用户首次访问页面,会拉取数据展示。输入筛选条件,点击查询后,会再次拉取数据在前端展示。

需求实现

使用React Class Component的写法

如果使用以前的class写法,简单写一下,代码可能大概长成下面这样:

import React from 'react'; import { Tabs, Input, RangeTime, Button, Table } from './components'; class App extends React.Component {   ...   state = {     type: [],     id: '',     title: '',     date: [],     dataList: []   }   componentDidMount() {     this.fetchData();   }   render() {     <Tabs value={this.state.type} onChange={this.handleTypeChange}/>     <Input value={this.state.id} label="ID" onChange={this.handleIdChange}/>     <Input value={this.state.id} label="标题" onChange={this.handleTitleChange}/>     <RangeTime value={this.state.date} onChange={this.handleRangeTimeChange}/>     <Button onClick={this.handleQueryBtnClick}>查询</Button>     <Table dataList={this.state.dataList} />   }      fetchData() {     ...     this.setState({       dataList     });   }   handleTypeChange() {     ...     this.setState({       type,     });   }      handleIdChange() {     ...     this.setState({       id,     });   }   handleTitleChange() {     ...     this.setState({       title,     });   }   handleRangeTimeChange() {     ...     this.setState({       date,     });   }   handleQueryBtnClick() {     ...   }   ... }

使用React Hooks的写法

关于React hooks的相关内容,这里就不赘述了。可以直接查看react官方文档,写得非常好。

https://reactjs.org/docs/hooks-intro.html

本次需求其实就两个逻辑:1、输入筛选项 。2、查询数据

主页面一个hooks,处理筛选项以及数据展示。数据请求逻辑单独弄一个hooks。

主页面hooks:

import React, { useState, useEffect} from 'react'; import { Tabs, Input, RangeTime, Button, Table } from './components'; const App = () => {   // 数据类型   const tabs = [{ key: 1, value: '类型1' }, { key: 0, value: '类型2' }];   const [tab, setTab] = useState(1);   // 数据ID   const [dataId, setDataid] = useState('');   // 标题   const [title, setTitle] = useState('');   // 时间区间, 默认为至今一周时间   const now = Date.now();   const [timeRange, setTimeRange] = useState([now - 1000 * 60 * 60 * 24 * 7, now]);   // 数据列表   const [dataList, setDataList] = useState([]);   // 点击搜索按钮   function handleBtnClick() {     // 请求数据     ...   }   return <section className="app">     <Title title="数据查询" />     <Tabs label="类型" tabs={tabs} tab={tab} onChange={setTab} />     <Input value={dataId} placeholder="请输入数据ID" onChange={setDataid}>ID</Input>     <Input value={title} placeholder="请输入数据标题" onChange={setTitle}>标题</Input>     <TimeRange label="数据时间" value={timeRange} onChange={handleTimeChange}/>     <article className="btn-container">       <Button type="primary" onClick={handleBtnClick}>         查询                 </Button>     </article>     <Table dataList={dataList}></Table>   </section> };

上面的代码,完成了筛选项的处理逻辑。下面来实现负责数据请求的hooks.

数据请求hooks:

import React, { useState, useEffect } from 'react'; import jsonp from '../tools/jsonp'; function MyFecth(url) {   // 是否正在请求中   const [isLoading, setIsLoanding] = useState(false);   // 请求参数   const [queryParams, setQueryParams] = useState(null);   // 请求结果   const [data, setData] = useState(null);   // 向接口发起请求   const fetchData = async () => {     if(queryParams === null) {       return;     }     setIsLoanding(true);     const res = await jsonp({       url: url,       data: queryParams     });     setData(res);     setIsLoanding(false);   }   // 只要queryParams改变,就发起请求   useEffect(()=> {     fetchData();   }, [queryParams]);   // 供外部调用   const doGet = (params) => {     setQueryParams(params);   }   return {     isLoading,     data,     doGet   } } export default MyFecth;

在主页面中,引用数据请求hooks:

import React, { useState, useEffect} from 'react'; import { Tabs, Input, RangeTime, Button, Table } from './components'; import MyFecth from './MyFetch'; const App = () => {   // ①使用数据请求hooks   const { isLoading, data, doGet } = MyFecth('http://xxx');      // 数据类型   const tabs = [{ key: 1, value: '类型1' }, { key: 0, value: '类型2' }];   const [tab, setTab] = useState(1);   // 数据ID   const [dataId, setDataid] = useState('');   // 标题   const [title, setTitle] = useState('');   // 时间区间, 默认为至今一周时间   const now = Date.now();   const [timeRange, setTimeRange] = useState([now - 1000 * 60 * 60 * 24 * 7, now]);   // 数据列表   const [dataList, setDataList] = useState([]);            // 点击搜索按钮   function handleBtnClick() {     // ②点击按钮后请求数据     const params = {};     title && (params.title = title);     dataId && (params.dataId = dataId);     params.startTime = String(timeRange[0]);     params.endTime = String(timeRange[1]);     doGet(params);   }      // ③data改变后,重新渲染列表。   // 这里相当于 componentDidUpdate。当data发生改变时,重新渲染页面   useEffect(() => {     setDataList(data);   }, [data]);      // ④首次进入页面时,无任何筛选项。拉取数据,渲染页面。   // useEffect第二个参数为一个空数组,相当于在 componentDidMount 时执行该「副作用」   useEffect(() => {     doGet({});   }, []);   return <section className="app">     <Title title="数据查询" />     <Tabs label="类型" tabs={tabs} tab={tab} onChange={setTab} />     <Input value={dataId} placeholder="请输入数据ID" onChange={setDataid}>ID</Input>     <Input value={title} placeholder="请输入数据标题" onChange={setTitle}>标题</Input>     <TimeRange label="数据时间" value={timeRange} onChange={handleTimeChange}/>     <article className="btn-container">       <Button type="primary" isLoading={isLoading} onClick={handleBtnClick}>         查询                 </Button>     </article>     <Table dataList={dataList}></Table>   </section> };

关于React Hooks的一些思考

使用hooks写完这个需求,最直观的感受就是,代码写起来很爽。不需要像以前那样写很多的setState。其次就是

hooks的api设计得很优秀,一个useState的就能将【状态】和【变更状态的逻辑】两两配对。React的基本思想就是【数据到视图的映射】,在hooks中,使用useEffect来表明其中的【副作用】,感觉react官方也倾向于不区分componentDidMount和componentDidUpdate。

从api设计就能看出,hooks提倡组件状态细粒度地拆分。在一个hooks组件中,可能包含很多的状态,如果用户的某些操作,需要同时修改两个状态,那么我需要分别调用这两个状态的修改逻辑,这样会导致组件被重新render两次。而在使用class写法的组件中,只需要一次setState就好。这样看来,hooks中render两次的操作,可能会带来些许的性能问题 ? 这就要求我们在设计组件结构和state时,多斟酌,多抽象。

关于“react hooks的示例分析”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI