React移动端开发项目优化

发布于:2025-07-11 ⋅ 阅读:(26) ⋅ 点赞:(0)

  1.搜索组件的优化

        先来回顾本来的搜索组件是怎么写的。

import React from 'react'
import classes from './FIlterMeals.module.css'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faSearch } from '@fortawesome/free-solid-svg-icons'
export default function FilterMeals(props) {
    const [keyword, setKeyWord] = React.useState('')
    const inputChange = (event) => {
    setKeyWord(event.target.value.trim())
    //trim()去掉字符串中的空格trim() 只会去掉字符串开头和结尾的空格;
    //props.filter(keyword)
        const keyword = event.target.value
        props.filter(keyword)
    }
    return (
        <div className={classes.FilterMeals}>
            <div className={classes.SearchBox}>
                <FontAwesomeIcon className={classes.SearchIcon} icon={faSearch} />
                <input value={keyword} onChange={Change} className={classes.SearchInput} type="text" name="" id="" placeholder={'请你输入内容'} />
            </div>
        </div>
    )
}

        我们直接去添加的监听事件,如果value变了那么就调用函数把输入的value当作keyword传过去,然后根组件里面筛选展示。        

   const filterHandle = (keyword) => {
        const newHbb = originHbb.filter((item) => { return (item.title.includes(keyword)) })
        // includes() 是否包含里面的字符串返回值truefalse和index Of()返回值        true 或 false        第一个匹配项的索引,找不到返回 -1
        setHbb(newHbb)
    }

·        但是这里我们希望用useEffect去监听value变化然后更新keyword,也就是把这个搜索组件变为受控组件。那么我们就需要去用useEffect书写代码。

   const Change = (event) => {
        setKeyWord(event.target.value)
    }
    React.useEffect(() => {
        console.log('effect触发了');
        props.filter(keyword)
    }, [keyword])

        这里keyword是用state设置的变量。然后我们用value={keyword}绑定输入框,用setKeyword(e.target.value)绑定state值。现在是受控组件,但是我们的组件还有一个问题。

         

        输入一个h的时候就开始筛选了导致没东西展示???这很明显用户不能接受,这样我们要怎么做呢?也就是每次只要开始输入东西,就会重新筛选数据,

         

         而且我们要知道useEffect可以发送请求拿回来数据的,我们这里只是学前端所以把数据放到根组件里面,但是实际上我们要发送请求拿回数据然后定义操作数据的函数。导致我们每次输入一个拼音就会发送请求??这显然不符合逻辑,会导致无数次访问服务器,甚至输入拼音的时候还会丢失列表。 

        我们就要去想我们怎么能在用户输出完之后去筛选呢?怎么判断用户输入完之后呢?

  React.useEffect(() => {
        //我们要降低数据过滤的次数,提高用户的体验
        //用户输入完了再过滤用户输入的过程中不要过滤
        //当用户停止输入1s后我们才去查询
        setTimeout(() => {
            console.log('effect触发了');
            props.filter(keyword)
        }, 1000)

    }, [keyword])

        这样我们好像给了用户一秒的输入时间,也就是说当keyword改变的时候,我们默认一秒用户输入时间,这样确实输入的时候拼音不会立马丢失了,但是服务器请求还是非常多次,这个问题没有解决反而更怪了。不仅调用非常多次而且还一秒后显示列表???

        

          输入一个汉堡包调用这么多次真实离谱,我甚至开了Reacttool工具看起来更多了。那怎么去优化呢?

        相当于还是hanbaobao一个拼音就调用一次。。。只不过筛选一秒后开始。。也就是说我们每次属于hanbaobao的时候每一次输入的字母比如我们输入h,计时器打开了,再次输入a,ha的计时器就打开了。。。所以每次输入新的都会重新再开启一个定时器。也就是说只要我们一直输入1s后肯定会出结果..

        所以我们应该在开启一个定时器的时候,关闭上一个定时器,保证输入完之后才执行。

        怎么关闭呢?这时候引出来我们钩子函数useEffect的另外一个功能,可以在回调函数中指定一个函数作为返回值,会在下一次执行effect前调用。这样我们就可以永远执行最新的输入内容计时器了。

        先测试一下。

 React.useEffect(() => {
        console.log('effect触发了');
             return (() => {
            console.log('回调函数执行了');
        }
    }, [keyword])

         

        确实是这样,那么我们就可以去执行删除前一个定时器了。

   React.useEffect(() => {
        const timer = setTimeout(() => {
             console.log('effect触发了');
            props.filter(keyword)
        }, 1000)
        return (() => {
             console.log('回调函数执行了');
            clearInterval(timer)
        })
    }, [keyword])

         

        这样我们就实现了输入完之后1s才回去调用查询函数。优化完毕。

        通过这个案例就可以更深入理解useEffect这个钩子函数了。 

 

        

        


网站公告

今日签到

点亮在社区的每一天
去签到