Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
306 views
in Technique[技术] by (71.8m points)

react hooks 搜索功能分页功能,有重复请求,帮忙指点指点。

import React, { useReducer, useEffect } from 'react'
import { View, Text, hideLoading } from 'remax/wechat';
import { usePageEvent } from 'remax/macro';
import { Loading, Cell, SearchBar } from 'anna-remax-ui';
import './index.less';
import { goodsList } from '@/api/index'
import cui from '@/utils/common';


export default () => {
  const initialState = {
    isLoading: true,
    isScroll: true,
    isInit: true,
    no_data: false,
    page_no: 1,
    page_size: 20,
    search_val: '',
    items: []
  }
  const reducer = (state, action) => {
    switch (action.type) {
      case 'loading':
        return { ...state, isLoading: action.data };
      case 'is_init':
        return { ...state, isInit: action.data };
      case 'no_data':
        return { ...state, no_data: action.data };
      case 'scroll':
        return { ...state, isScroll: action.data };
      case 'search_val':
        return { ...state, search_val: action.data };
      case 'initItems':
        return { ...state, items: action.data };
      case 'addItems':
        return { ...state, items: state.items.concat(action.data) };
      case 'page_no':
        return { ...state, page_no: action.data };
      default:
        throw new Error();
    }
  }
  const [model, dispatch] = useReducer(reducer, initialState)

  usePageEvent('onReachBottom', () => {
    dispatch({ type: 'is_init', data: false })
    if (model.isScroll) {
      dispatch({ type: 'page_no', data: model.page_no + 1 })
    }
  });
  useEffect(() => {
    dispatch({ type: 'initItems', data: [] })
  }, [model.search_val])
  useEffect(() => {
    setTimeFun()
  }, [model.search_val, model.page_no])

  const initFun = (e) => {
    dispatch({ type: 'is_init', data: true })
    dispatch({ type: 'page_no', data: 1 })
    dispatch({ type: 'search_val', data: e })
  }

  const setTimeFun = () => {
    if (model.isInit) {
      dispatch({ type: 'scroll', data: true })
    }
    dispatch({ type: 'no_data', data: false })
    dispatch({ type: 'loading', data: true })
    setTimeout(() => getPage(), 500)
  }
  const getPage = () => {
    const { page_no, isInit, search_val } = model
    const pararms = {
      page_no: page_no,
      page_size: 20,
    }
    if (search_val !== '') {
      pararms.name = search_val
    }
    goodsList(pararms).then(res => {
      const { data, msg, status } = res
      dispatch({ type: 'loading', data: false })
      if (status === 200) {
        if (isInit) {
          if (data.pages === page_no || data.items.length === 0) {
            dispatch({ type: 'scroll', data: false })
            dispatch({ type: 'no_data', data: true })
          }
          dispatch({ type: 'initItems', data: data.items })
        } else {
          dispatch({ type: 'addItems', data: data.items })
        }
        if (data.pages === page_no) {
          dispatch({ type: 'scroll', data: false })
          dispatch({ type: 'no_data', data: true })
        }
      } else {
        cui.toast(msg)
      }
    })
  }
  const goPage = (e) => {
    const url = `?id=${e.id}&&name=${e.name}&&stock=${e.stock}`
    cui.href('/pages/goods_info/index' + url)
  }

  return (
    <View className="goodsListPage">
      <View className="search bg-white">
        <SearchBar
          placeholder="搜索"
          shape="square"
          inputStyle={{
            border: '2px solid #2ea44f',
            backgroundColor: '#FDFFFD',
          }}
          onClear={() => dispatch({ type: 'search_val', data: '' })}
          onSubmit={(e) => {
            initFun(e)
          }}
        />
      </View>
      {
        model.items.map(item => {
          return (
            <Cell key={item.id} label={item.name} border arrow onTap={() => goPage(item)}>
              <Text className={item.stock < 4 ? 'text-red' : 'text-grey'}>库存:{item.stock}</Text>
            </Cell>
          )
        })
      }
      {model.no_data && (
        <View className="text-gray text-center padding-tb">哎呦,没了~!</View>
      )}
      {
        model.isLoading && (
          <View className="text-center padding-top-sm">
            <Loading type="wave" />
          </View>
        )
      }
    </View>
  );
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

这种情况上防抖同时处理好异步时序就可以了,没必要非纠结变化的来源在哪儿。。。
https://github.com/rxliuli/ex...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...