Appearance
上拉 - 下拉加载更多实现
本节目标:理解“上拉 - 下拉加载更多实现”的核心思路,并能把它用于实际开发或面试表达。 ==在这里==
Scroll==基础组件的作用就展现出来了。之前我们封装了==Scroll==组件,监听上拉==/==下拉刷新的功能已编写完成,但是相应的==loading==效果并没有考虑。现在,我们就来先完善==loading==效果。== ==首先引入==loading==组件:==
import Loading from '../loading/index';==将== return ==部分的代码修改为==
:
const PullUpdisplayStyle = pullUpLoading ? {display: ""} : { display:"none" };const PullDowndisplayStyle = pullDownLoading ? { display: ""} : { display:"none" };return ( <ScrollContainer ref={scrollContaninerRef}> {props.children} {/*==滑到底部加载动画==
*/} <PullUpLoading style={ PullUpdisplayStyle }><Loading></Loading></PullUpLoading> {/*==顶部下拉刷新动画==
*/} <PullDownLoading style={ PullDowndisplayStyle }><LoadingV2></LoadingV2></PullDownLoading> </ScrollContainer>);==注意== PullUpdisplayStyle ==和== PullDowndisplayStyle ==都是外部传入的,这就方便了我们控制== loading ==的显示和隐藏。== ==其中== Loading ==组件即之前编写的两圆交错的涟漪效果组件,但== LoadingV2 ==并没有编写,现在就花一点时间来开发第二个== Loading ==效果。==
//baseUI/loading-v2/index.jsimport React from 'react';import styled, {keyframes} from'styled-components';import style from '../../assets/global-style'
const dance = keyframes` 0%, 40%, 100%{ transform: scaleY (0.4); transform-origin: center 100%; } 20%{ transform: scaleY (1); }`const Loading = styled.div` height: 10px; width: 100%; margin: auto; text-align: center; font-size: 10px; >div { display: inline-block; background-color: ${style ["theme-color"]}; height: 100%; width: 1px; margin-right:2px; animation: ${dance} 1s infinite; } >div:nth-child (2) { animation-delay: -0.4s; } >div:nth-child (3) { animation-delay: -0.6s; } >div:nth-child (4) { animation-delay: -0.5s; } >div:nth-child (5) { animation-delay: -0.2s; }
`
function LoadingV2 () { return ( <Loading> <div></div> <div></div> <div></div> <div></div> <div></div> <span >==拼命加载中==
...</span> </Loading> );} export default React.memo (LoadingV2);
OK,==现在在== scroll ==组件中引入。==
//scroll/index.jsimport Loading2 from '../loading-v2/index';==接下来,我们在== Singers/index.js ==中,传入相应的参数即可。==
<Scroll pullUp={ handlePullUp } pullDown = { handlePullDown } pullUpLoading = { pullUpLoading } pullDownLoading = { pullDownLoading }> { renderSingerList () }</Scroll>==现在== handlePullUp ==和== handlePullDown ==两个方法还没有定义,添加如下==
:
const handlePullUp = () => { pullUpRefreshDispatch (category, alpha, category === '', pageCount);};
const handlePullDown = () => { pullDownRefreshDispatch (category, alpha);};==现在试一试上拉下拉,相应的== loading ==动画能够出现了,同时数据也能正常加载。== ==对了,现在进场的== loading ==效果还没有实现,我们在== Singers/index.js ==中加入==
:
import Loading from '../../baseUI/loading';//...//ListContainer==标签中==
<Loading show={enterLoading}></Loading>==这样,当你第一次打开列表页或者切换不同分类的时候,会有== loading ==效果出现,和我们的预期一致。== 相关优化图片懒加载 ==同样是引入== react-lazyload, ==在== Singers/index.js ==作如下修改==
:
//==首先引入==
import LazyLoad, {forceCheck} from 'react-lazyload';
//==包裹== img ==标签==
<LazyLoad placeholder={<img width="100%" height="100%" src={require ('./singer.png')} alt="music"/>}> <img src={`${item.picUrl}?param=300x300`} width="100%" height="100%" alt="music"/></LazyLoad>
<Scroll //... onScroll={forceCheck}></Scroll>==现在懒加载的效果就完成了。== 防抖处理 ==当你频繁地下拉时,事实上事件回调函数也会被频繁触发,导致发送很多无意义的请求。因此这里对== Scroll ==基础组件做一下防抖处理。== ==防抖函数写在== api/utils.js ==中,==
//==防抖函数==
export const debounce = (func, delay) => { let timer; return function (...args) { if (timer) { clearTimeout (timer); } timer = setTimeout (() => { func.apply (this, args); clearTimeout (timer); }, delay); }}==然后在== scroll/index.js ==中==
:
import { debounce } from "../../api/utils";
//...
let pullUpDebounce = useMemo (() => { return debounce (pullUp, 300)}, [pullUp]);//==千万注意,这里不能省略依赖,==
//==不然拿到的始终是第一次== pullUp ==函数的引用,相应的闭包作用域变量都是第一次的,产生闭包陷阱。下同。==
let pullDownDebounce = useMemo (() => { return debounce (pullDown, 300)}, [pullDown]);//...//==之后直接调用== useMemo ==返回的函数==
//==滑动到底部==
if (bScroll.y <= bScroll.maxScrollY + 100){ pullUpDebounce ();}
//==判断用户的下拉动作==
if (pos.y > 50) { pullDownDebounce ();}==这样当你频繁上拉下拉的时候就不会频繁触发回调了。== ==思考题:当我们切换组件的时候,事实上现在的== category ==和== alpha ==会丢失,如果想要切换组件后仍然能够缓存== category ==和== alpha ==的值应该怎么做?可以自己动手试试看。== > 来自
<https://juejin.im/book/5da96626e51d4524ba0fd237/section/5da975b7518825092e1605c3>