React 图片瀑布流

 思路:

根据浏览器宽度,确定列数,请求的图片列表数据是列数的10倍,按列数取数据渲染

React 图片瀑布流_第1张图片

Index.js:

import React from 'react'
import { connect } from 'react-redux'
import { withRouter } from 'react-router-dom'
import { SinglePageHeader } from '../../../../../components/light'
import InfiniteScroll from 'react-infinite-scroll-component'
import { Divider, Skeleton } from 'antd'
import useList from './useList'
import LazyLoad from 'react-lazy-load'

import './index.css'

function Index(props) {
  const {
    dataSource,
    isHasMore,
    columnCount,
    handleSearch,
    handleImgDrawSameStyleClick,
  } = useList(props)
  return (
    
handleSearch({ page: 1, isRefresh: true })} pullDownToRefresh pullDownToRefreshThreshold={50} pullDownToRefreshContent={

↓ 下拉刷新

} releaseToRefreshContent={

↑ 释放刷新

} hasMore={isHasMore} loader={ } endMessage={ dataSource.length === 0 ? null : ( 已经到底啦~ ) } scrollableTarget="scrollableDiv" >
{Array.from({ length: columnCount }, () => '').map( (item, index) => (
{dataSource .filter( (item, dataSourceIndex) => dataSourceIndex % columnCount === index ) .map((item) => (
图片 handleImgDrawSameStyleClick(item)} >
))}
) )}
{dataSource.length === 0 ? ( ) : null}
) } const mapStateToProps = (state) => { return { collapsed: state.getIn(['light', 'collapsed']), isRNGotToken: state.getIn(['light', 'isRNGotToken']), } } const mapDispatchToProps = (dispatch) => { return { onSetState(key, value) { dispatch({ type: 'SET_LIGHT_STATE', key, value }) }, onDispatch(action) { dispatch(action) }, } } export default connect(mapStateToProps, mapDispatchToProps)(withRouter(Index))

useList.js:

import { useState, useEffect } from 'react'
import { Form } from 'antd'
import Api from '../../../../../api'
import { message } from 'antd'
import * as clipboard from 'clipboard-polyfill/text'

export default function useList(props) {
  const [total, setTotal] = useState(10)
  const [current, setCurrent] = useState(1)
  let tempCount = Math.floor((window.innerWidth - 10) / 180)
  tempCount = Math.floor((window.innerWidth - (5 + tempCount * 5)) / 180)

  console.log('tempCount1', tempCount)
  //把dataSource和pageSize单独放在一起是为了避免切换pageSize时的bug
  const [state, setState] = useState({
    dataSource: [],
    pageSize: tempCount * 10,
  })
  const [isHasMore, setIsHasMore] = useState(true)
  // eslint-disable-next-line
  const [username, setUsername] = useState(localStorage.getItem('username'))
  const [form] = Form.useForm()
  // eslint-disable-next-line
  const [initValues, setInitValues] = useState({})
  // eslint-disable-next-line
  const [columnCount, setColumnCount] = useState(tempCount)

  //搜索
  const handleSearch = ({
    page = current,
    pageSize = state.pageSize,
    isRefresh = false,
  } = {}) => {
    if (isRefresh) {
      setState({
        dataSource: [],
        pageSize: tempCount * 10,
      })
    }
    let searchData = { pageNum: page, pageSize }
    Api.h5.sdImgSearch(searchData).then((res) => {
      if (res.code === 200) {
        const { pageNum, pageSize, total } = res.data
        let list = res.data.list
        if (isRefresh) {
          setState({
            dataSource: [...list],
            pageSize: res.data.pageSize,
          })
        } else {
          setState({
            dataSource: [...state.dataSource, ...list],
            pageSize: res.data.pageSize,
          })
        }
        setTotal(res.data.total)
        const currentTemp = res.data.pageNum + 1
        setCurrent(currentTemp)
        setIsHasMore(pageNum < Math.ceil(total / pageSize))
      }
    })
  }

  //添加或编辑
  const handleFinish = (values) => {
    console.log('Success:', values)
    Api.h5.exchangeCodeAppUse(values).then((res) => {
      if (res.code === 200) {
        message.success('恭喜您,兑换成功')
        //props.history.push('/h5/index/me')
      }
    })
  }

  //校验失败
  const handleFinishFailed = (errorInfo) => {
    console.log('Failed:', errorInfo)
  }

  //退出
  const handleQuit = () => {
    Api.light.userLogout().then((res) => {
      if (res.code === 200) {
        props.history.push('/h5/login')
        window.localStorage.removeItem('username')
        window.localStorage.removeItem('token')
      }
    })
  }

  //跳转
  const handleJumpPage = (path) => {
    // eslint-disable-next-line
    props.history.push(path)
  }

  const handleCopy = (text) => {
    clipboard.writeText(text).then(() => {
      message.success('复制成功')
    })
  }

  const handleImgDrawSameStyleClick = (item) => {
    console.log(item)
    props.history.push(
      `/single/home/sdSimple?modelId=${item.id}&name=${item.name}&link=${item.link}&imgUid=${item.imgUid}`
    )
  }

  useEffect(() => {
    if (window.platform === 'rn') {
      if (props.isRNGotToken === true) {
        handleSearch()
      }
    } else {
      handleSearch()
    }
    // eslint-disable-next-line
  }, [props.isRNGotToken])

  return {
    username,
    form,
    initValues,
    dataSource: state.dataSource,
    total,
    current,
    pageSize: state.pageSize,
    isHasMore,
    columnCount,
    handleFinish,
    handleFinishFailed,
    handleQuit,
    handleJumpPage,
    handleCopy,
    handleSearch,
    handleImgDrawSameStyleClick,
  }
}

index.css:

.m-ai-img-wrap-box{display: flex;justify-content: center;background: #ddd;background: #ddd;position: absolute;top: 0;left: 0;right: 0;bottom: 0;overflow: hidden;}
.m-ai-img-wrap-chat{position: relative; display: flex;flex-direction: column;width: 100%;background: #ededed;}
.m-ai-img-main{flex:1;display: flex;flex-direction: column;overflow-y: auto;}
.m-ai-img-list{flex: 1;padding: 0px 0;overflow-y: auto;}
.m-ai-img-list-inner{position: relative;padding: 0 0 0 5px; display: flex; flex-wrap: wrap;justify-content: center;}
.m-ai-img-list-column{display: flex;flex-direction: column;width: 175px;margin: 0 5px 0 0;}
.m-ai-img-lazy-load{position: relative;min-width: 175px; display: flex;flex-direction: column;justify-content: center; min-height: 175px;margin: 0 0 5px 0;border-radius: 5px; background: #dddddd;}
.m-ai-img{width: 175px;border-radius: 5px;}

效果图:

React 图片瀑布流_第2张图片

React 图片瀑布流_第3张图片

参考链接:

https://chat.xutongbao.top/

你可能感兴趣的:(web前端,react.js,前端,javascript)