当前位置: 代码迷 >> 综合 >> React-Hooks-04-自定义hook的四个典型使用场景
  详细解决方案

React-Hooks-04-自定义hook的四个典型使用场景

热度:22   发布时间:2023-10-18 16:53:30.0

简单的例子,简单计数器实现,抽离业务逻辑成为hook:

function useCounter() {const [count, setCount] = useState(0)const increment = useCallback(() => {setCount(count + 1)}, [count])const decrement = useCallback(() => {setCount(count - 1)}, [count])const reset = useCallback(() => {setCount(0)}, [count])return { count, increment, decrement, reset }
}

在组件中使用这个hook:

function Counter() {const { count, increment, decrement, reset } = useCounter()return (<div><p>{ count }</p><button onClick={decrement}>-</button><button onClick={increment}>+</button><button onClick={reset}>reset</button></div>)
}

和高阶组件相比,更加简单

  • 三个典型业务场景

  • 封装通用逻辑:useAsync

    • 如:发起异步请求获取数据并显示在界面上

处理这类请求时,模式都是类似的,通常遵循下面的步骤:

  1. 创建data、loading、error这3个state

  2. 请求发出后,设置loading state为true

  3. 请求成功后,将返回的数据放到某个state中,并将loading state设为false

  4. 请求失败后,设置error state为true,并将loading state设为false

最后,基于state、loading、error这三个state数据,UI就可以正确显示数据了

将逻辑抽离出来:

const useAsync = (asyncFunction) => {// 设置3个异步逻辑相关的stateconst [data, setDate] = useState(null)cosnt [loading, setLoading] = useState(false)const [error, setError] = useState(null)// 定义一个callback用于执行异步逻辑const execute = useCallback(() => {setLoading(true)setData(null)setError(null)return asyncFunction().then((response) => {setData(response)setLoading(false)}).catch((erro) => {setError(erro)setLoading(false)})}, [asyncFunction])return { execute, loading, data, error }
}

在组件中使用:

function UserList() {const {execute: fetchUsers,data: users,loading,error} => useAsync(async() => {const res = await fetch("http://req/api/users/")const json = await res.json()return json.data // response})return (// UI...)
}
  • 监听浏览器状态:useScroll

    • 界面需要根据在窗口大小变化重新布局

    • 在页面滚动时,需要根据滚动条位置,来决定是否显示一个“返回顶部”的按钮

对应到这个场景就是:

    -组件需要绑定到当前滚动条的位置数据上

const getPosition = () => {return {x: document.body.scrollLeft,y: document.body.scrollTop}
}const useScroll = () => {const [position, setPosition] = useState(getPosition())useEffect(() => {const handler = () => {setPosition(getPosition())}document.addEventListener("scroll", handler)return () => {document.removeEventListener("scroll", handler)}}, [])return position
}

使用,是否展示返回顶部:

function ScrollTop {const { y } = useScroll()const goTop = useCallback(()=> {document.body.scrollTop = 0}, [])// y会根据scroll动态改变if ( y > 300 ) {return (<button onClick={goTop}>Back to Top</button>)}return null
}

  相关解决方案