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 useTransition in favor of useNavigation #5687

Merged
merged 1 commit into from
Mar 7, 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
5 changes: 5 additions & 0 deletions .changeset/deprecate-use-transition.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@remix-run/react": patch
---

Deprecate `useTransition` in favor of `useNavigation`
61 changes: 56 additions & 5 deletions docs/hooks/use-transition.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ title: useTransition

# `useTransition`

<docs-error>This API will be removed in v2 in favor of [`useNavigation`][use-navigation]. You can start using the new `useNavigation` hook today to make upgrading in the future easy, but you can keep using `useTransition` until v2.</docs-error>

---

<docs-success>Watch the <a href="https://www.youtube.com/playlist?list=PLXoynULbYuEDG2wBFSZ66b85EIspy3fy6">📼 Remix Singles</a>: <a href="https://www.youtube.com/watch?v=y4VLIFjFq8k&list=PLXoynULbYuEDG2wBFSZ66b85EIspy3fy6">Pending UI</a>, <a href="https://www.youtube.com/watch?v=bMLej7bg5Zo&list=PLXoynULbYuEDG2wBFSZ66b85EIspy3fy6">Clearing Inputs After Form Submissions</a>, and <a href="https://www.youtube.com/watch?v=EdB_nj01C80&list=PLXoynULbYuEDG2wBFSZ66b85EIspy3fy6">Optimistic UI</a></docs-success>

This hook tells you everything you need to know about a page transition to build pending navigation indicators and optimistic UI on data mutations. Things like:
Expand Down Expand Up @@ -114,11 +118,62 @@ function SubmitButton() {
}
```

### Moving away from `transition.type`

The `type` field has been removed in the new `useNavigation` hook (which will replace `useTransition` in Remix v2). We've found that `state` is sufficient for almost all use-cases, and when it's not you can derive sub-types via `navigation.state` and other fields. Also note that the `loaderSubmission` type is now represented with `state: "loading"`. Here's a few examples:

```js
function Component() {
let navigation = useNavigation();

let isActionSubmission =
navigation.state === "submitting";

let isActionReload =
navigation.state === "loading" &&
navigation.formMethod != null &&
navigation.formMethod != "get" &&
// We had a submission navigation and are loading the submitted location
navigation.formAction === navigation.pathname;

let isActionRedirect =
navigation.state === "loading" &&
navigation.formMethod != null &&
navigation.formMethod != "get" &&
// We had a submission navigation and are now navigating to different location
navigation.formAction !== navigation.pathname;

let isLoaderSubmission =
navigation.state === "loading" &&
navigation.state.formMethod === "get" &&
// We had a loader submission and are navigating to the submitted location
navigation.formAction === navigation.pathname;

let isLoaderSubmissionRedirect =
navigation.state === "loading" &&
navigation.state.formMethod === "get" &&
// We had a loader submission and are navigating to a new location
navigation.formAction !== navigation.pathname;
}
```

## `transition.submission`

Any transition that started from a `<Form>` or `useSubmit` will have your form's submission attached to it. This is primarily useful to build "Optimistic UI" with the `submission.formData` [`FormData`][form-data] object.

TODO: Example
### Moving away from `transition.submission`

The `submission` field has been removed in the new `useNavigation` hook (which will replace `useTransition` in Remix v2) and the same sub-fields are now exposed directly on the `navigation`:

```js
function Component() {
let navigation = useNavigation();
// navigation.formMethod
// navigation.formAction
// navigation.formData
// navigation.formEncType
}
```

## `transition.location`

Expand Down Expand Up @@ -149,10 +204,6 @@ function PendingLink({ to, children }) {

Note that this link will not appear "pending" if a form is being submitted to the URL the link points to, because we only do this for "loading" states. The form will contain the pending UI for when the state is "submitting", once the action is complete, then the link will go pending.

## v2 deprecation

This API will be removed in v2 in favor of [`useNavigation`][use-navigation]. You can start using the new `useNavigation` hook today to make upgrading in the future easy, but you can keep using `useTransition` before v2.

[usefetcher]: ./use-fetcher
[form-data]: https://developer.mozilla.org/en-US/docs/Web/API/FormData
[use-navigation]: ./use-navigation
13 changes: 13 additions & 0 deletions packages/remix-react/components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ import type {
TransitionStates,
} from "./transition";
import { IDLE_TRANSITION, IDLE_FETCHER } from "./transition";
import { warnOnce } from "./warnings";

function useDataRouterContext() {
let context = React.useContext(DataRouterContext);
Expand Down Expand Up @@ -1173,11 +1174,23 @@ export function useActionData<T = AppData>(): SerializeFrom<T> | undefined {
* Returns everything you need to know about a page transition to build pending
* navigation indicators and optimistic UI on data mutations.
*
* @deprecated in favor of useNavigation
*
* @see https://remix.run/hooks/use-transition
*/
export function useTransition(): Transition {
let navigation = useNavigation();

React.useEffect(() => {
warnOnce(
false,
"⚠️ DEPRECATED: The `useTransition` hook has been deprecated in favor of " +
"`useNavigation` and will be removed in Remix v2. Please update your " +
"code to leverage `useNavigation`.\n\nSee https://remix.run/docs/hooks/use-transition " +
"and https://remix.run/docs/hooks/use-navigation for more information."
);
}, []);

return React.useMemo(
() => convertNavigationToTransition(navigation),
[navigation]
Expand Down
8 changes: 8 additions & 0 deletions packages/remix-react/warnings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const alreadyWarned: { [message: string]: boolean } = {};

export function warnOnce(condition: boolean, message: string): void {
if (!condition && !alreadyWarned[message]) {
alreadyWarned[message] = true;
console.warn(message);
}
}