Skip to content

Commit

Permalink
feat(react): 新增 useStateWithDeps
Browse files Browse the repository at this point in the history
  • Loading branch information
fjc0k committed Sep 19, 2020
1 parent 59ecc3d commit dff9b73
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/react/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ export * from './useEnvironment'
export * from './useLoadMore'
export * from './useReachBottom'
export * from './useScrollLoadMore'
export * from './useStateWithDeps'
export * from './useValidator'
// @endindex

Expand Down
68 changes: 68 additions & 0 deletions src/react/useStateWithDeps.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { act, renderHook } from '@testing-library/react-hooks'
import { useStateWithDeps } from './useStateWithDeps'

describe('useStateWithDeps', () => {
test('依赖为空时正常', () => {
const { result, rerender } = renderHook(
props => {
const [id, setId] = useStateWithDeps(props.id, [])
return { id, setId }
},
{
initialProps: {
id: 1,
},
},
)
expect(result.current.id).toBe(1)
rerender({ id: 2 })
expect(result.current.id).toBe(1)
act(() => result.current.setId(2))
expect(result.current.id).toBe(2)
})

test('依赖不为空时正常', () => {
const { result, rerender } = renderHook(
props => {
const [id, setId] = useStateWithDeps(props.id, [props.id])
return { id, setId }
},
{
initialProps: {
id: 1,
},
},
)
expect(result.current.id).toBe(1)
rerender({ id: 2 })
expect(result.current.id).toBe(2)
act(() => result.current.setId(3))
expect(result.current.id).toBe(3)
})

test('状态为函数时正常', () => {
const fn = jest.fn()
const { result, rerender } = renderHook(
props => {
const [id, setId] = useStateWithDeps(() => {
fn()
return props.id
}, [props.id])
return { id, setId }
},
{
initialProps: {
id: 1,
},
},
)
expect(result.current.id).toBe(1)
expect(fn).toBeCalled().toBeCalledTimes(1)
rerender({ id: 2 })
expect(result.current.id).toBe(2)
expect(fn).toBeCalled().toBeCalledTimes(2)
act(() => result.current.setId(3))
expect(result.current.id).toBe(3)
expect(fn).toBeCalled().toBeCalledTimes(2)
})
})
20 changes: 20 additions & 0 deletions src/react/useStateWithDeps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React, { useState } from 'react'
import { useUpdateEffect } from 'react-use'

/**
* 给 useState 插上依赖的翅膀。依赖变化时会更新状态。
*
* @param state 状态
* @param deps 依赖
* @returns 返回结果同 useState
*/
export function useStateWithDeps<S>(
state: S | (() => S),
deps: React.DependencyList,
): [S, React.Dispatch<React.SetStateAction<S>>] {
const [value, setValue] = useState(state)
useUpdateEffect(() => {
setValue(state)
}, deps)
return [value, setValue]
}

0 comments on commit dff9b73

Please sign in to comment.