基于React实现下拉刷新效果
作者:卡卡舅舅
这篇文章主要介绍了如何基于react实现下拉刷新效果,在下拉的时候会进入loading状态,文中有详细的代码示例供大家参考,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
简介
本文基于react实现下拉刷新效果,在下拉的时候会进入loading状态。
实现效果
效果如上图所示,在下拉到底部时候,会出现loading条,在处理完成后loading条消失。
具体代码
布局 & 逻辑
import {useRef, useState} from "react"; export const ScrollView = ({loadingComponent, contentComponent}) => { const LoadingComponent = loadingComponent; const ContentComponent = contentComponent; /** * 加载状态 */ const [loading, setLoading] = useState(false); /** * 滚动容器引用 */ const scrollRef = useRef(null); let contentStyle = {height: '30px', width:'100%', textAlign:'center', display:'none'}; if (loading){ // 加载中显示 contentStyle = {height: '30px', width:'100%', textAlign:'center'}; scrollRef.current.scrollTop = 0; // 滚到头部 } const handleScroll = ()=>{ const {scrollTop} = scrollRef.current; if (scrollTop > 50 && !loading){ setLoading(true); // 设置为加载中状态 // 模拟数据加载 setTimeout(()=>{ setLoading(false); // 加载完成 }, 3000) } } return ( <div style={{height: '200px', overflow:'auto', width:'40%'}} ref={scrollRef} onScroll={handleScroll}> <div style={contentStyle}> <LoadingComponent/> </div> <div style={{height:'300px', width:'100%'}}> <ContentComponent/> </div> </div> ) }
使用demo
import {ScrollView} from "./component/scroll-view/ScrollView"; const App = ()=> { return ( <ScrollView loadingComponent={Loading} contentComponent={Content}> </ScrollView> ) } const Loading = ()=>{ return <div>loading</div> } const Content = ()=>{ return <div> hello, world</div> } export default App;
番外:上拉加载实现
1、下载react-pullload
npm i react-pullload
2、在组件中去引用
import ReactPullLoad,{ STATS } from "react-pullload";
3、css样式
①引用插件内的样式
import "node_modules/react-pullload/dist/ReactPullLoad.css";
②或者直接引入使用下列代码:
.pull-load { position: relative; overflow-y: scroll; -webkit-overflow-scrolling: touch; } .pull-load-head { position: absolute; transform: translate3d(0px, -100%, 0px); width: 100%; } .state-refreshing .pull-load-head, .state-refreshed .pull-load-head { position: relative; transform: none; } .pull-load-body { position: relative; } .state-refreshing .pull-load-body { transition: transform 0.2s; } .state-reset .pull-load-body { transition: transform 0.2s; } .pull-load-head-default { text-align: center; font-size: 12px; line-height: 0.8rem; color: #7676a1; } .state-pulling .pull-load-head-default:after { content: '下拉刷新'; } .state-pulling.enough .pull-load-head-default:after { content: '松开刷新'; } .state-refreshing .pull-load-head-default:after { content: '正在刷新...'; } .state-refreshed .pull-load-head-default:after { content: '刷新成功'; } .state-pulling .pull-load-head-default { opacity: 1; } .state-pulling .pull-load-head-default i { display: inline-block; font-size: 0.3rem; margin-right: .6em; margin-top: -3px; vertical-align: middle; height: 0.3rem; border-left: 1px solid; position: relative; transition: transform .3s ease; } .state-pulling .pull-load-head-default i:before, .state-pulling .pull-load-head-default i:after { content: ''; position: absolute; font-size: .5em; width: 1em; bottom: 0px; border-top: 1px solid; } .state-pulling .pull-load-head-default i:before { right: 1px; transform: rotate(50deg); transform-origin: right; } .state-pulling .pull-load-head-default i:after { left: 0px; transform: rotate(-50deg); transform-origin: left; } .state-pulling.enough .pull-load-head-default i { transform: rotate(180deg); } .state-refreshing .pull-load-head-default i { margin-right: 10px; margin-top: -3px; display: inline-block; vertical-align: middle; font-size: 0.3rem; width: 0.3rem; height: 0.3rem; border: 2px solid #9494b6; border-top-color: #fff; border-radius: 100%; animation: circle .8s infinite linear; } .state-refreshed .pull-load-head-default { opacity: 1; transition: opacity 1s; } .state-refreshed .pull-load-head-default i { display: inline-block; box-sizing: content-box; vertical-align: middle; margin-right: 10px; margin-top: -3px; font-size: 14px; height: 1em; width: 1em; border: 2px solid; border-radius: 100%; position: relative; } .state-refreshed .pull-load-head-default i:before { content: ''; position: absolute; top: -2px; left: 4px; height: 11px; width: 5px; border: solid; border-width: 0 2px 2px 0; transform: rotate(40deg); } .pull-load-footer-default { text-align: center; font-size: 12px; line-height: 0.8rem; color: #7676a1; } .state-loading .pull-load-footer-default:after { content: '加载更多'; } .pull-load-footer-default.nomore:after { content: '没有更多'; } .state-loading .pull-load-footer-default i { margin-right: 10px; margin-top: -3px; display: inline-block; vertical-align: middle; font-size: 0.3rem; width: 0.3rem; height: 0.3rem; border: 2px solid #9494b6; border-top-color: #fff; border-radius: 100%; animation: circle .8s infinite linear; } @keyframes circle { 100% { transform: rotate(360deg); } }
4、pullLoad标签包裹
<ReactPullLoad downEnough={150} ref="reactpullload" className="block" *加上下面注释的属性会出问题 // isBlockContainer={true} action={this.state.action} handleAction={this.handleAction} hasMore={this.state.hasMore} style={{paddingTop: 132}} distanceBottom={1000}> ..... this is list </ReactPullLoad>
5、scroll函数
constructor(props) { super(props); this.state = { // scroll 相关 hasMore: true, action: STATS.init, } } // 滚动条 handleAction = (action) => { if(action === this.state.action || action === STATS.refreshing && this.state.action === STATS.loading || action === STATS.loading && this.state.action === STATS.refreshing){ return false } if(action === STATS.refreshing){//刷新 setTimeout(()=>{ //refreshing complete 下拉刷新 }, 1000) } else if(action === STATS.loading){//加载更多 this.setState({ hasMore: true }); setTimeout(()=>{ if(this.state.index === this.state.curPage){ this.setState({ action: STATS.reset, hasMore: false }); } else{ 上拉加载.... } }, 1000) } this.setState({ action: action }) }
到此这篇关于基于React实现下拉刷新效果的文章就介绍到这了,更多相关React下拉刷新内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!