question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[RFC] Hooks rename and types terminology simplification

See original GitHub issue

[RFC] Hooks rename and types terminology simplification

With the recent internal and open-source releases of Recoil we have received lots of useful feedback (thank you!). From these discussions we have prepared a terminology and hook name cleanup to help simplify and clarify concepts.

For this simplification the core state concept in Recoil would become just “Recoil State.” The Flow/TypeScript types and React hooks interface would be renamed to consolidate on RecoilState. Instead of using RecoilState vs RecoilValue to distinguish writability, all types would just be RecoilState, with special read-only or writable variants.

Atoms and selectors continue to both be types of RecoilState, and the use of them from components should be indistinguishable. Atoms are built with the atom() factory and represent state managed by Recoil while selectors are built with the selector() factory and represent state derived from other Recoil state or external requests.

We do recognize that API change can be disruptive, so we want proceed carefully. For the most part we can support this change by simply supporting both the new and old hook names before later removing the deprecated hooks. We are also planning to explore a code-mod script to aid in migration.

TypeScript and Flow Types

The TypeScript and Flow types would be updated to reflect the unified “Recoil State” terminology. RecoilState<T> represents either a read-only or writable state. Note that the read-only type has a covariant type parameter, which can be very helpful for interfaces. The writable type could also be extended to support different read and write types for selector abstraction.

  • RecoilState<T>RecoilValue<T>
  • RecoilStateReadOnly<+T>RecoilValueReadOnly<+T>
  • RecoilStateWritable<R, W = R>RecoilState<T>

Hooks

By unifying on the “Recoil State” terminology, we can then simplify the hook names as well:

  • Recoil State
    • useRecoilState()
      • The core hook for Recoil that mostly matches the semantics of React’s useState().
      • Passing it a RecoilStateWritable<R,W> will return a tuple with the value and a setter callback.
      • What’s new is now the hook could also be passed a RecoilState<T> or RecoilStateReadOnly<T>, in which case it will return a tuple with just the read-only value and no setter callback.
    • useRecoilValue() - No change
      • Returns just the atom value.
    • useRecoilLoadable()useRecoilValueLoadable()
      • Returns the Recoil state as a Loadable without using Suspense.
    • useRecoilSetter()useSetRecoilState()
      • Returns a setter callback to change the value for a RecoilStateWritable<R,W> type.
      • Potentially this version of this hook could take no parameters and returns a setter callback that dynamically provides the RecoilStateWritable<R,W> state to set.
    • useRecoilResetter()useResetRecoilState()
      • Returns a resetter callback to revert a RecoilStateWritable<R,W> .
      • This version could also use no parameters and provide a callback that accepts the atom/selector to reset.
    • useRecoilRefresher() <- useRecoilRefresher_UNSTABLE()
      • Update to take no parameters and provide a callback which accepts the atom/selector to refresh.
    • useRecoilStateLoadable() - Deprecated
    • useRecoilGetInfo_UNSTABLE()useGetRecoilValueInfo_UNSTABLE()
      • Gets information about the current status of an atom or selector
  • Snapshots - No change
    • useRecoilSnapshot()
    • useGotoRecoilSnapshot()
    • useRecoilTransactionObserver_UNSTABLE() - This hook may be deprecated.
  • useRecoilCallback() - No change
  • useRecoilTransaction_UNSTABLE() - No change
  • useRecoilStoreID() - No change
  • useRecoilBridgeAcrossReactRoots() - No change

Helper Utils

  • isRecoilState()isRecoilValue() - Helper to determine if a variable holds a Recoil atom or selector type.

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:24
  • Comments:13 (4 by maintainers)

github_iconTop GitHub Comments

21reactions
ianstormtaylorcommented, Dec 18, 2020

Hey @drarmstr it’s great to see this! This was actually one of the issues I was going to bring up, so it’s nice to see that you’re open to changing the naming system. I think the proposed names are better than the current ones (the current “value” vs. “state” is very confusing), but I think they could be improved further.

I think the issues are:

  • They are very verbose compared to the average hook. Which is not very nice when you consider that multiple of these could be used per component. It looks like the new names are actually more verbose overall too.
  • They’re not great in terms of autocomplete, since most of them start with useRecoilState it takes a long time before you get to a unique aspect of the hook name to filter on.
  • They’re still not as clear to me as I think they could be for common concepts like “read”, “write”, “reset”.

I was going to suggest a core set of hooks that looked like:

// The most basic, likely most often used.
[value, setValue, resetValue] = useRecoil(...)

// For just reading a value.
value = useRecoilValue(...)

// For just writing a value.
setValue = useRecoilSet(...)

// For just reseting a value.
resetValue = useRecoilReset(...)

This makes them easier to read quickly, is better for autocomplete, and I think it pretty clear as far as intuitively understanding what the more specific hooks help you with.

You could also do:

useRecoilRead
useRecoilWrite
useRecoilReset

And either way it would be easy to extend for the extended set of hooks you mentioned:

// Get info about an atom/selector.
info = useRecoilInfo(...)

// Get a loadable without suspending.
loadable = useRecoilLoadable(...)

useRecoilSnapshot(...)
useRecoilCallback(...)
...

I think given that Recoil is a library that is completely built around managing state, having to write “State” everywhere becomes really tedious for no real gain in specificity. Similarly you could even simplify:

isRecoil(...)

Looking at how nice and terse the built-in React hooks are (eg. useMemo, useCallback, useState, useReducer), it would be a shame not to have a similarly terse setup for something used as often as Recoil.

17reactions
drarmstrcommented, Jan 4, 2021

Please note the RFC has been updated to remove the State based on feedback.

Read more comments on GitHub >

github_iconTop Results From Across the Web

[RFC] Remove Types - MLIR - LLVM Discussion Forums
When (if) types get merged into attributes, types and attributes can be kept syntactically seperate, but the only issue would be overlapping ...
Read more >
2318-custom-test-frameworks - The Rust RFC Book
A mechanism for cargo integration so that custom test frameworks are at the same level of integration as test or bench as far...
Read more >
draft-ietf-trill-rbridge-options-07
Initial extensions have been specified in RFC [ExtendHeader]. ... 1.1 Conventions used in this document The terminology and acronyms defined in [RFC6325] ...
Read more >
OpenLDAP Software 2.4 Administrator's Guide
Multiple suffix lines can be given, and usually at least one is required for each database definition. (Some backend types, such as frontend...
Read more >
Administration Guide Red Hat Directory Server 11
Using this plug-in with chaining helps simplify the management of static groups when the group members are remote to the static group definition....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found