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

feat(ra-core): remove useSafeSetState hook #10341

Merged
merged 5 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from 3 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
6 changes: 3 additions & 3 deletions examples/crm/src/login/LoginForm.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as React from 'react';
import { useState } from 'react';
geobde marked this conversation as resolved.
Show resolved Hide resolved
import { styled } from '@mui/material/styles';
import {
Button,
Expand All @@ -7,7 +7,7 @@ import {
CircularProgress,
Typography,
} from '@mui/material';
import { Form, useLogin, useNotify, useSafeSetState } from 'ra-core';
import { Form, useLogin, useNotify } from 'ra-core';
erwanMarmelab marked this conversation as resolved.
Show resolved Hide resolved
import { Login, TextInput } from 'react-admin';
import { SubmitHandler } from 'react-hook-form';
import { Link } from 'react-router-dom';
Expand Down Expand Up @@ -36,7 +36,7 @@ const StyledForm = styled(Form, {
}));

export const LoginForm = () => {
const [loading, setLoading] = useSafeSetState(false);
const [loading, setLoading] = useState(false);
const login = useLogin();
const notify = useNotify();

Expand Down
5 changes: 2 additions & 3 deletions packages/ra-core/src/auth/useLogoutIfAccessDenied.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import { useEffect } from 'react';
import { useEffect, useState } from 'react';
import expect from 'expect';
import { render, screen, waitFor } from '@testing-library/react';
import { Routes, Route } from 'react-router-dom';
Expand All @@ -9,7 +9,6 @@ import { AuthContext } from './AuthContext';
import useLogout from './useLogout';
import { useNotify } from '../notification/useNotify';
import { AuthProvider } from '../types';
import { useSafeSetState } from '../util';

import { TestMemoryRouter } from '../routing';

Expand Down Expand Up @@ -40,7 +39,7 @@ const authProvider: AuthProvider = {
};

const TestComponent = ({ error }: { error?: any }) => {
const [loggedOut, setLoggedOut] = useSafeSetState(false);
const [loggedOut, setLoggedOut] = useState(false);
const logoutIfAccessDenied = useLogoutIfAccessDenied();
useEffect(() => {
logoutIfAccessDenied(error).then(setLoggedOut);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { useCallback, useEffect, useRef } from 'react';
import { useCallback, useEffect, useRef, useState } from 'react';
import { UseQueryOptions } from '@tanstack/react-query';
import get from 'lodash/get';
import isEqual from 'lodash/isEqual';
import lodashDebounce from 'lodash/debounce';

import { useSafeSetState, removeEmpty } from '../../util';
import { removeEmpty } from '../../util';
import { useGetManyReference } from '../../dataProvider';
import { useNotify } from '../../notification';
import { FilterPayload, Identifier, RaRecord, SortPayload } from '../../types';
Expand Down Expand Up @@ -93,10 +93,10 @@ export const useReferenceManyFieldController = <

// filter logic
const filterRef = useRef(filter);
const [displayedFilters, setDisplayedFilters] = useSafeSetState<{
const [displayedFilters, setDisplayedFilters] = useState<{
[key: string]: boolean;
}>({});
const [filterValues, setFilterValues] = useSafeSetState<{
const [filterValues, setFilterValues] = useState<{
[key: string]: any;
}>(filter);
const hideFilter = useCallback(
Expand Down
31 changes: 17 additions & 14 deletions packages/ra-core/src/controller/list/useList.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useCallback, useEffect, useRef } from 'react';
import { useCallback, useEffect, useRef, useState } from 'react';
import get from 'lodash/get';
import isEqual from 'lodash/isEqual';
import { removeEmpty, useSafeSetState } from '../../util';
import { removeEmpty } from '../../util';
import { FilterPayload, RaRecord, SortPayload } from '../../types';
import { useResourceContext } from '../../core';
import usePaginationState from '../usePaginationState';
Expand Down Expand Up @@ -68,19 +68,22 @@ export const useList = <RecordType extends RaRecord = any>(
} = props;
const resource = useResourceContext(props);

const [fetchingState, setFetchingState] = useSafeSetState<boolean>(
isFetching
) as [boolean, (isFetching: boolean) => void];
const [fetchingState, setFetchingState] = useState<boolean>(isFetching) as [
boolean,
(isFetching: boolean) => void,
];

const [loadingState, setLoadingState] = useSafeSetState<boolean>(
isLoading
) as [boolean, (isLoading: boolean) => void];
const [loadingState, setLoadingState] = useState<boolean>(isLoading) as [
boolean,
(isLoading: boolean) => void,
];

const [pendingState, setPendingState] = useSafeSetState<boolean>(
isPending
) as [boolean, (isPending: boolean) => void];
const [pendingState, setPendingState] = useState<boolean>(isPending) as [
boolean,
(isPending: boolean) => void,
];

const [finalItems, setFinalItems] = useSafeSetState<{
const [finalItems, setFinalItems] = useState<{
data?: RecordType[];
total?: number;
}>(() => ({
Expand Down Expand Up @@ -115,10 +118,10 @@ export const useList = <RecordType extends RaRecord = any>(

// filter logic
const filterRef = useRef(filter);
const [displayedFilters, setDisplayedFilters] = useSafeSetState<{
const [displayedFilters, setDisplayedFilters] = useState<{
[key: string]: boolean;
}>({});
const [filterValues, setFilterValues] = useSafeSetState<{
const [filterValues, setFilterValues] = useState<{
[key: string]: any;
}>(filter);
const hideFilter = useCallback(
Expand Down
5 changes: 2 additions & 3 deletions packages/ra-core/src/controller/useFilterState.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { useEffect, useRef, useCallback } from 'react';
import { useEffect, useRef, useCallback, useState } from 'react';
import debounce from 'lodash/debounce';
import isEqual from 'lodash/isEqual';

import { useSafeSetState } from '../util';
import { FilterPayload } from '../types';

interface UseFilterStateOptions {
Expand Down Expand Up @@ -60,7 +59,7 @@ export default ({
}: UseFilterStateOptions): UseFilterStateProps => {
const permanentFilterProp = useRef(permanentFilter);
const latestValue = useRef<string>();
const [filter, setFilterValue] = useSafeSetState<FilterPayload>({
const [filter, setFilterValue] = useState<FilterPayload>({
...permanentFilter,
...filterToQuery(''),
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
} from 'react';
import useLogout from '../auth/useLogout';
import usePermissions from '../auth/usePermissions';
import { useSafeSetState } from '../util/hooks';
import {
AdminChildren,
RenderResourcesFunction,
Expand Down Expand Up @@ -83,7 +82,7 @@ const useRoutesAndResourcesFromChildren = (
const [routesAndResources, setRoutesAndResources, mergeRoutesAndResources] =
useRoutesAndResourcesState(getRoutesAndResourceFromNodes(children));

const [status, setStatus] = useSafeSetState<AdminRouterStatus>(() =>
const [status, setStatus] = useState<AdminRouterStatus>(() =>
getStatus({
children,
...routesAndResources,
Expand Down
29 changes: 2 additions & 27 deletions packages/ra-core/src/util/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,8 @@
import * as React from 'react';
import { useState, useRef, useEffect, useCallback } from 'react';
import { useRef, useEffect, useState } from 'react';
import isEqual from 'lodash/isEqual';

// thanks Kent C Dodds for the following helpers

export function useSafeSetState<T>(
fzaninotto marked this conversation as resolved.
Show resolved Hide resolved
initialState?: T | (() => T)
): [T | undefined, React.Dispatch<React.SetStateAction<T>>] {
const [state, setState] = useState(initialState);

const mountedRef = useRef(false);
useEffect(() => {
mountedRef.current = true;
return () => {
mountedRef.current = false;
};
}, []);
const safeSetState = useCallback(
args => {
if (mountedRef.current) {
return setState(args);
}
},
[mountedRef, setState]
);

return [state, safeSetState];
}

export function usePrevious(value) {
const ref = useRef();
useEffect(() => {
Expand All @@ -54,7 +29,7 @@ export function useDeepCompareEffect(callback, inputs) {
* @returns true if the delay has expired, false otherwise
*/
export function useTimeout(ms = 0, key = '') {
const [ready, setReady] = useSafeSetState(false);
const [ready, setReady] = useState(false);

useEffect(() => {
setReady(false);
Expand Down
11 changes: 2 additions & 9 deletions packages/ra-ui-materialui/src/auth/LoginForm.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
import * as React from 'react';
import { styled } from '@mui/material/styles';
import { Button, CardContent, CircularProgress } from '@mui/material';
import {
Form,
required,
useTranslate,
useLogin,
useNotify,
useSafeSetState,
} from 'ra-core';
import { Form, required, useTranslate, useLogin, useNotify } from 'ra-core';
import { TextInput } from '../input';

export const LoginForm = (props: LoginFormProps) => {
const { redirectTo, className } = props;
const [loading, setLoading] = useSafeSetState(false);
const [loading, setLoading] = React.useState(false);
const login = useLogin();
const translate = useTranslate();
const notify = useNotify();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import { Fragment, ReactElement } from 'react';
import { Fragment, ReactElement, useState } from 'react';
import ActionDelete from '@mui/icons-material/Delete';

import { alpha, styled } from '@mui/material/styles';
Expand All @@ -11,7 +11,6 @@ import {
useRefresh,
useResourceContext,
useTranslate,
useSafeSetState,
RaRecord,
DeleteManyParams,
} from 'ra-core';
Expand All @@ -38,7 +37,7 @@ export const BulkDeleteWithConfirmButton = (
} = props;
const { meta: mutationMeta, ...otherMutationOptions } = mutationOptions;
const { selectedIds, onUnselectItems } = useListContext();
const [isOpen, setOpen] = useSafeSetState(false);
const [isOpen, setOpen] = useState(false);
const notify = useNotify();
const resource = useResourceContext(props);
const refresh = useRefresh();
Expand Down