使用react使用微网页时遇到的问题
list的上拉加载问题(基于antd,而不是antd-mobile)
- 想实现一个上拉加载下一页的功能,因为UI组件用的时antd,所以就使用了一下antd中的
List
的滚动加载 - 使用这个滚动加载的时候需要结合
react-infinite-scroller
这个组件 实现滚动自动加载列表。 - 实现过程如下:
state = {
pageNo: 1,
pageSize: 10,
data: [],
loading: false,
hasMore: true,
count: 0,
}
fetchData = callback => {
const { searchName, searchSort, pageNo, pageSize } = this.state;
const params = {
pageNo,
pageSize,
};
getHomeProducts(params).then(res => {
if (res.success) {
callback(res);
}
});
};
componentWillMount() {
this.fetchData(res => {
this.setState({
data: res.data.records,
count: res.data.totalCount,
});
});
}
handleInfiniteOnLoad = () => {
let { data, pageNo } = this.state;
const { count } = this.state;
this.setState({
loading: true,
pageNo: (pageNo += 1),
});
if (data.length >= count) {
this.setState({
hasMore: false,
loading: false,
});
return;
}
this.fetchData(res => {
data = data.concat(res.data.records);
this.setState({
data,
loading: false,
});
});
};
<InfiniteScroll
initialLoad={false}
pageStart={this.state.pageNo}
loadMore={this.handleInfiniteOnLoad}
hasMore={!this.state.loading && this.state.hasMore}
useWindow={false}
>
<List
dataSource={this.state.data}
renderItem={(item, index) => (
<div className={style.listDiv}>
<ProductItem dataInfor={item} key={item.id} />
</div>
)}
>
{this.state.loading && this.state.hasMore && (
<div className={style.demoloadingcontainer}>
<Spin />
</div>
)}
</List>
</InfiniteScroll>
上面的那个上拉加载存在一个问题,就是从详情页返回的时候会滚动条不会定位,下面是解决问题的方法
- 在vue中有keep-alive可以帮助我们更好的进行页面缓存
- 但是react的话我没有找到比较好用的插件,或者是找到的插件老是报错的问题,所以我就用自己的方法实现了这一逻辑
- 过程如下:
- 我在页面跳转之前,在销毁时期的生命周期函数中把所需要的一些数据(列表数据 以及一些搜索字段)存在了localStorage里面(判断一下跳转页面是不是详情页)
componentWillUnmount () {
const { searchName,searchSort,minMoq,maxMoq,minPrice,maxPrice,searchProvince,searchCity,pageNo,pageSize,data,loading,hasMore,count,loadState} = this.state
const storageData = { searchName,searchSort,minMoq,maxMoq,minPrice,maxPrice,searchProvince,searchCity,pageNo,pageSize,data,loading,hasMore,count,loadState}
const nextPath = window.location.pathname
nextPath==='/mProductDetail'?
localStorage.setItem("storageData",JSON.stringify(storageData))
:null
}
- 监听一下列表这个元素scroll,通过
onScroll
这个事件把scrollTop
属性值存在localStorage
里面 - 进入列表的时候,在生命周期函数
componentDidMount
中判断是不是从详情页进入的,如果是的话 ,那把state里面的搜索字段。数据列表字段都使用localStorage
里面的,如果不是的话 那就请求 - 如果使用缓存数据的话 ,在把组件中的state数据修改为存储的那些数据后,需要及时清除
localStorage
里面的数据componentDidMount() {
if(JSON.parse(localStorage.getItem('storageData'))){
const { searchName,searchSort,minMoq,maxMoq,minPrice,maxPrice,searchProvince,searchCity,pageNo,pageSize,data,loading,hasMore,count,loadState} = JSON.parse(localStorage.getItem('storageData'))
this.setState({
searchName,searchSort,minMoq,maxMoq,minPrice,maxPrice,searchProvince,searchCity,pageNo,pageSize,data,loading,hasMore,count,loadState
},()=> {
document.getElementById('list').scrollTop=JSON.parse(localStorage.getItem('scrollTop'))
localStorage.removeItem('storageData')
localStorage.removeItem('scrollTop')
})
} else {
this.fetchData(res => {
this.setState({
data: res.data.records,
count: res.data.totalCount,
});
})
}
this.fetchNationRegionTree();
}
轮播图中图片的预览问题(ui组件是antd)
- 在一个详情页面中有一个轮播图,希望点击轮播图的某一个图片进行图片预览,在预览的同时也可以进行图片上一个,下一个
- 在网上找了一个插件
react-zmage
官网地址是这里 - 首先安装
cnpm install react-zmage -S
- 引入
import Zmage from 'react-zmage'
- 然后我们只需要把
img
标签替换成Zmage
标签就好。这样只是单独一个图片的预览。 - 我们希望轮播图中的图片列表在预览的时候都可以看到,那么需要设置
set
和defaultPage
这两个属性
Zmage中的 set属性和defaultPage的使用
<Zmage
controller={{ download: false, zoom: false}}
src={item.url} alt=''
defaultPage={index}
set={this.state.imgList}
preset='mobile'
/>
Zmage在h5页面中会有一个报错
Unable to preventDefault inside passive event listener due to target being treated as passive.
- 上面这个报错是在点击和滑动的时候的报错
- 解决办法就是在我的css文件中加入
* { touch-action: pan-y; }