Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate useSafeState #1096

Merged
merged 2 commits into from
Mar 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ If you are contributing for the first time, we recommend reading this
- The hook should be developed with SSR in mind, meaning that usage of hook in SSR environment
should not lead to errors.
- If your hook reuses other @react-hookz/web hooks, import them as
`import { useSafeState } from '../useSafeState';` instead of
`import { useSafeState } from '..';`
`import { useToggle } from '../useToggle';` instead of
`import { useToggle } from '..';`
2. Re-export the hook implementation and all its custom types in `src/index.ts`.
3. Fully test your hook. The tests should include tests for both DOM and SSR environments.
- Hook's tests should be placed in `__tests__` subdirectory, next to the source file - `dom.ts`
Expand Down
6 changes: 2 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ Coming from `react-use`? Check out our
- [**`useCounter`**](https://react-hookz.github.io/web/?path=/docs/state-usecounter--example)
— Tracks a numeric value and offers functions for manipulating it.
- [**`useDebouncedState`**](https://react-hookz.github.io/web/?path=/docs/state-usedebouncedstate--example)
— Like `useSafeState` but its state setter is debounced.
— Like `useState` but its state setter is debounced.
- [**`useFunctionalState`**](https://react-hookz.github.io/web/?path=/docs/state-usefunctionalstate--page)
— Like `useState` but instead of raw state, a state getter function is returned.
- [**`useList`**](https://react-hookz.github.io/web/?path=/docs/state-uselist--example)
Expand All @@ -137,14 +137,12 @@ Coming from `react-use`? Check out our
Like `React.useState`, but state is only updated within animation frame.
- [**`useRenderCount`**](https://react-hookz.github.io/web/?path=/docs/state-userendercount--example) —
Tracks component's render count including first render.
- [**`useSafeState`**](https://react-hookz.github.io/web/?path=/docs/state-usesafestate--page) —
Like `useState`, but its state setter is guarded against setting the state of an unmounted component.
- [**`useSet`**](https://react-hookz.github.io/web/?path=/docs/state-useset--example) — Tracks the
state of a `Set`.
- [**`useToggle`**](https://react-hookz.github.io/web/?path=/docs/state-usetoggle--example) — Like
`useState`, but can only be `true` or `false`.
- [**`useThrottledState`**](https://react-hookz.github.io/web/?path=/docs/state-usethrottledstate--example)
— Like `useSafeState` but its state setter is throttled.
— Like `useState` but its state setter is throttled.
- [**`useValidator`**](https://react-hookz.github.io/web/?path=/docs/state-usevalidator--example)
— Performs validation when any of the provided dependencies change.

Expand Down
1 change: 0 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ export * from './usePreviousDistinct';
export * from './useQueue';
export * from './useRafState';
export * from './useRenderCount';
export * from './useSafeState';
export * from './useSet';
export * from './useToggle';
export * from './useThrottledState';
Expand Down
5 changes: 2 additions & 3 deletions src/useAsync/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { useMemo, useRef } from 'react';
import { useSafeState } from '../useSafeState';
import { useMemo, useRef, useState } from 'react';
import { useSyncedRef } from '../useSyncedRef';

export type AsyncStatus = 'loading' | 'success' | 'error' | 'not-executed';
Expand Down Expand Up @@ -68,7 +67,7 @@ export function useAsync<Result, Args extends unknown[] = unknown[]>(
asyncFn: (...params: Args) => Promise<Result>,
initialValue?: Result
): [AsyncState<Result | undefined>, UseAsyncActions<Result, Args>, UseAsyncMeta<Result, Args>] {
const [state, setState] = useSafeState<AsyncState<Result | undefined>>({
const [state, setState] = useState<AsyncState<Result | undefined>>({
status: 'not-executed',
error: undefined,
result: initialValue,
Expand Down
5 changes: 2 additions & 3 deletions src/useCookieValue/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
/* eslint-disable @typescript-eslint/no-use-before-define,no-use-before-define */
import Cookies from 'js-cookie';
import { Dispatch, useCallback, useEffect } from 'react';
import { Dispatch, useCallback, useEffect, useState } from 'react';
import { useFirstMountState } from '../useFirstMountState';
import { useMountEffect } from '../useMountEffect';
import { useSafeState } from '../useSafeState';
import { useSyncedRef } from '../useSyncedRef';
import { isBrowser } from '../util/const';

Expand Down Expand Up @@ -125,7 +124,7 @@ export function useCookieValue(
});

const isFirstMount = useFirstMountState();
const [state, setState] = useSafeState<string | null | undefined>(
const [state, setState] = useState<string | null | undefined>(
isFirstMount && initializeWithValue ? methods.current.fetchVal() : undefined
);

Expand Down
10 changes: 5 additions & 5 deletions src/useDebouncedState/__docs__/story.mdx
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { Canvas, Meta, Story } from '@storybook/addon-docs';
import { Example } from './example.stories';
import { ImportPath } from '../../__docs__/ImportPath';
import { Canvas, Meta, Story } from '@storybook/addon-docs'
import { Example } from './example.stories'
import { ImportPath } from '../../__docs__/ImportPath'

<Meta title="State/useDebouncedState" component={Example} />

# useDebouncedState

Like `useSafeState` but its state setter is debounced.
Like `useState` but its state setter is debounced.

#### Example

Expand All @@ -30,7 +30,7 @@ export function useDebouncedState<S>(

#### Arguments

- **initialState** _`S | (() => S)`_ - Initial state to pass to underlying `useSafeState`.
- **initialState** _`S | (() => S)`_ - Initial state to pass to underlying `useState`.
- **delay** _`number`_ - Debounce delay.
- **maxWait** _`number`_ _(default: `0`)_ - The maximum time `callback` is allowed to be delayed
before it's invoked. `0` means no max wait.
Expand Down
9 changes: 4 additions & 5 deletions src/useDebouncedState/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { Dispatch, SetStateAction } from 'react';
import { Dispatch, SetStateAction, useState } from 'react';
import { useDebouncedCallback } from '../useDebouncedCallback';
import { useSafeState } from '../useSafeState';

/**
* Like `useSafeState` but its state setter is debounced.
* Like `useState` but its state setter is debounced.
*
* @param initialState Initial state to pass to underlying `useSafeState`.
* @param initialState Initial state to pass to underlying `useState`.
* @param delay Debounce delay.
* @param maxWait Maximum amount of milliseconds that function can be delayed
* before it's force execution. 0 means no max wait.
Expand All @@ -15,7 +14,7 @@ export function useDebouncedState<S>(
delay: number,
maxWait = 0
): [S, Dispatch<SetStateAction<S>>] {
const [state, setState] = useSafeState(initialState);
const [state, setState] = useState(initialState);

return [state, useDebouncedCallback(setState, [], delay, maxWait)];
}
4 changes: 2 additions & 2 deletions src/useFunctionalState/__docs__/story.mdx
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Meta } from '@storybook/addon-docs';
import { Meta } from '@storybook/addon-docs'

<Meta title="State/useFunctionalState" />

# useFunctionalState

Like `useState` but instead of raw state, state getter returned. `useSafeState` is used underneath.
Like `useState` but instead of raw state, state getter returned.

## Reference

Expand Down
8 changes: 3 additions & 5 deletions src/useFunctionalState/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Dispatch, SetStateAction, useCallback } from 'react';
import { useSafeState } from '../useSafeState';
import { Dispatch, SetStateAction, useCallback, useState } from 'react';
import { useSyncedRef } from '../useSyncedRef';

export function useFunctionalState<S>(
Expand All @@ -11,13 +10,12 @@ export function useFunctionalState<S = undefined>(): [
];

/**
* Like `useState` but instead of raw state, state getter returned. `useSafeState` is
* used underneath.
* Like `useState` but instead of raw state, state getter returned.
*/
export function useFunctionalState<S>(
initialState?: S | (() => S)
): [() => S | undefined, Dispatch<SetStateAction<S | undefined>>] {
const [state, setState] = useSafeState(initialState);
const [state, setState] = useState(initialState);
const stateRef = useSyncedRef(state);

// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down
7 changes: 4 additions & 3 deletions src/useHookableRef/__docs__/example.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import * as React from 'react';
import { useHookableRef, useSafeState } from '../..';
import { useState } from 'react';
import { useHookableRef } from '../..';

export const Example: React.FC = () => {
const [get, setGet] = useSafeState<Date>();
const [set, setSet] = useSafeState<Date>();
const [get, setGet] = useState<Date>();
const [set, setSet] = useState<Date>();

const ref = useHookableRef(
123,
Expand Down
5 changes: 2 additions & 3 deletions src/useIntersectionObserver/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { RefObject, useEffect } from 'react';
import { useSafeState } from '../useSafeState';
import { RefObject, useEffect, useState } from 'react';

const DEFAULT_THRESHOLD = [0];
const DEFAULT_ROOT_MARGIN = '0px';
Expand Down Expand Up @@ -135,7 +134,7 @@ export function useIntersectionObserver<T extends Element>(
rootMargin = DEFAULT_ROOT_MARGIN,
}: UseIntersectionObserverOptions = {}
): IntersectionObserverEntry | undefined {
const [state, setState] = useSafeState<IntersectionObserverEntry>();
const [state, setState] = useState<IntersectionObserverEntry>();

useEffect(() => {
const tgt = target && 'current' in target ? target.current : target;
Expand Down
5 changes: 3 additions & 2 deletions src/useIntervalEffect/__docs__/example.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as React from 'react';
import { useIntervalEffect, useSafeState, useToggle } from '../..';
import { useState } from 'react';
import { useIntervalEffect, useToggle } from '../..';

export const Example: React.FC = () => {
const [state, setState] = useSafeState<Date>();
const [state, setState] = useState<Date>();
const [enabled, toggleEnabled] = useToggle();

useIntervalEffect(
Expand Down
9 changes: 4 additions & 5 deletions src/useMeasure/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { MutableRefObject } from 'react';
import { UseResizeObserverCallback, useResizeObserver } from '../useResizeObserver';
import { MutableRefObject, useState } from 'react';
import { useResizeObserver, UseResizeObserverCallback } from '../useResizeObserver';
import { useHookableRef } from '../useHookableRef';
import { useRafCallback } from '../useRafCallback';
import { useSafeState } from '../useSafeState';

export interface Measures {
width: number;
Expand All @@ -17,14 +16,14 @@ export interface Measures {
export function useMeasure<T extends Element>(
enabled = true
): [Measures | undefined, MutableRefObject<T | null>] {
const [element, setElement] = useSafeState<T | null>(null);
const [element, setElement] = useState<T | null>(null);
const elementRef = useHookableRef<T | null>(null, (v) => {
setElement(v);

return v;
});

const [measures, setMeasures] = useSafeState<Measures>();
const [measures, setMeasures] = useState<Measures>();
const [observerHandler] = useRafCallback<UseResizeObserverCallback>((entry) =>
setMeasures({ width: entry.contentRect.width, height: entry.contentRect.height })
);
Expand Down
8 changes: 3 additions & 5 deletions src/useMediatedState/__docs__/story.mdx
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { Canvas, Meta, Story } from '@storybook/addon-docs';
import { Example } from './example.stories';
import { ImportPath } from '../../__docs__/ImportPath';
import { Canvas, Meta, Story } from '@storybook/addon-docs'
import { Example } from './example.stories'
import { ImportPath } from '../../__docs__/ImportPath'

<Meta title="State/useMediatedState" component={Example} />

# useMediatedState

Like `useState`, but every value (including initial) set is passed through mediator function.

> This hook uses `useSafeState` underneath, so it is safe to use its `setState` in async hooks.

> `setState` returned by this hook is stable between renders.

#### Example
Expand Down
5 changes: 2 additions & 3 deletions src/useMediatedState/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Dispatch, useCallback } from 'react';
import { useSafeState } from '../useSafeState';
import { Dispatch, useCallback, useState } from 'react';
import { useSyncedRef } from '../useSyncedRef';
import { InitialState, NextState, resolveHookState } from '../util/resolveHookState';

Expand All @@ -22,7 +21,7 @@ export function useMediatedState<State, RawState = State>(
initialState?: InitialState<State>,
mediator?: (state: RawState | State | undefined) => State
): [State | undefined, Dispatch<NextState<RawState, State | undefined>>] {
const [state, setState] = useSafeState(() => {
const [state, setState] = useState(() => {
return mediator ? mediator(resolveHookState(initialState)) : initialState;
});
const mediatorRef = useSyncedRef(mediator);
Expand Down
5 changes: 2 additions & 3 deletions src/useNetworkState/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import { isBrowser } from '../util/const';
import { useSafeState } from '../useSafeState';
import { off, on } from '../util/misc';
import { InitialState } from '../util/resolveHookState';

Expand Down Expand Up @@ -103,7 +102,7 @@ function getConnectionState(previousState?: UseNetworkState): UseNetworkState {
* Tracks the state of browser's network connection.
*/
export function useNetworkState(initialState?: InitialState<UseNetworkState>): UseNetworkState {
const [state, setState] = useSafeState(initialState ?? getConnectionState);
const [state, setState] = useState(initialState ?? getConnectionState);

useEffect(() => {
const handleStateChange = () => {
Expand Down
5 changes: 2 additions & 3 deletions src/usePermission/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { MutableRefObject, useEffect } from 'react';
import { useSafeState } from '../useSafeState';
import { MutableRefObject, useEffect, useState } from 'react';
import { off, on } from '../util/misc';

export type UsePermissionState = PermissionState | 'not-requested' | 'requested';
Expand All @@ -10,7 +9,7 @@ export type UsePermissionState = PermissionState | 'not-requested' | 'requested'
* @param descriptor Permission request descriptor that passed to `navigator.permissions.query`
*/
export function usePermission(descriptor: PermissionDescriptor): UsePermissionState {
const [state, setState] = useSafeState<UsePermissionState>('not-requested');
const [state, setState] = useState<UsePermissionState>('not-requested');

useEffect(() => {
const unmount: MutableRefObject<(() => void) | null> = { current: null };
Expand Down
5 changes: 2 additions & 3 deletions src/useRafState/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Dispatch, SetStateAction } from 'react';
import { Dispatch, SetStateAction, useState } from 'react';
import { useRafCallback } from '../useRafCallback';
import { useSafeState } from '../useSafeState';
import { useUnmountEffect } from '../useUnmountEffect';

export function useRafState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>];
Expand All @@ -15,7 +14,7 @@ export function useRafState<S = undefined>(): [
export function useRafState<S>(
initialState?: S | (() => S)
): [S | undefined, Dispatch<SetStateAction<S>>] {
const [state, innerSetState] = useSafeState<S | undefined>(initialState);
const [state, innerSetState] = useState<S | undefined>(initialState);

const [setState, cancelRaf] = useRafCallback(innerSetState);

Expand Down
5 changes: 2 additions & 3 deletions src/useRerender/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import { useCallback } from 'react';
import { useSafeState } from '../useSafeState';
import { useCallback, useState } from 'react';

const stateChanger = (state: number) => (state + 1) % Number.MAX_SAFE_INTEGER;

/**
* Return callback function that re-renders component.
*/
export function useRerender(): () => void {
const [, setState] = useSafeState(0);
const [, setState] = useState(0);

return useCallback(() => {
setState(stateChanger);
Expand Down
24 changes: 0 additions & 24 deletions src/useSafeState/__docs__/story.mdx

This file was deleted.

Loading