RFC: React Hooks

In this RFC, we propose introducing Hooks to React. See the RFC and the documentation for more details.
https://reactjs.org/docs/hooks-overview.html
View formatted RFC
(The talk video has now been published too.)

Nov 16 Update by @sophiebits:
See @sebmarkbage’s comment https://github.com/reactjs/rfcs/pull/68#issuecomment-439314884 for a detailed response to the preceding comments that covers various tradeoffs and articulates why we’ve landed on the current design. If you have something to say, please check that it is not answered there already.

Question about persisting values of useState - is the preferred way to create a custom usePersistedState hook that calls into storage mechanism?
I was wondering if there was a way to batch the write operations in environments such as React Native and how did you approach that problem at Facebook during your initial adoption?

Is this the right place for feedback? First of all - amazing work. I love where this is going with composability. My big question is about performance of Hooks.
Are all these function hooks redefined and recalled on every render?

Just watched the React Conf keynote, awesome presentation, super excited to give hooks a shot!
Not sure if this is the right place to ask but was wondering how function components that make use of hooks affect server-side rendering. In useEffects() for example, will errors be thrown when accessing browser apis like window during ssr?

@pcmaffey Looks like this FAQ entry addresses your performance concern.

Very exciting, this looks awesome!
Questioning the tuple return type:
const [count, setCount] = useState(0);

Why an array tuple instead of an object containing count and setCount members? Is this for performance (and if so, do we have numbers to show browsers or Node behaving strongly differently)? It feels like leaving the returned object open to adding more fields might make it easier to remain backwards compatible in the future, similar to how APIs often end up taking in single objects as a parameter rather than long lists of parameters.
const { count, setCount } = useState(0);

@JoshuaKGoldberg How would you customize those object properties? Array is the only way it works with custom naming.

Why an array tuple instead of an object containing count and setCount members?

You can assign names you need. Object destructuring requires you to put specific keys. You may end up having something like
let { state: name, setState: setName } = useState('Name')
let { state: surname, setState: setSurname } = useState('Surname');

Which is not the case with tuples.

I'm confused about when you would use useCallback vs when you would use useMemo, what am I missing?

It is a very early time for Hooks, so some integrations like DevTools support or Flow/TypeScript typings may not be ready yet.

Will I be able to inspect what hooks a component is using?
Having an object with named properties as state made it easy to see what's what. I guess this will be hard with the new useState?

Woah 👍

@eps1lon According to the FAQ, useState is backed by a list of anonymous memory cells:

There is an internal list of “memory cells” associated with each component. They’re just JavaScript objects where we can put some data. When you call a Hook like useState(), it reads the current cell (or initializes it during the first render), and then moves the pointer to the next one. This is how multiple useState() calls each get independent local state.

So if you ever find yourself trying to debug the underlying state, you're probably going to be working with a linked list of unnamed values. To figure out which memory cell is which, you'll have to refer back to the order of your useState calls.
Full disclosure: I'm planning to open an issue today to discuss a system for providing meaningful names for your useState calls, which should significantly relax the current usage restrictions, and eliminate the need for a linter to enforce those rules.

Positional effects (using any of these use* functions is an effect, even just to read state) worry me. It seems easy to get wrong, and doing so might not present until production. For the same reason it also seems like it'll be extremely difficult to introduce to beginners -- "the magic function works here but not there".
Using Symbols instead of positional keys would make it easier to understand and harder to get wrong:
const $count = Symbol("count");

function MyComponent() {
  const [count, setCount] = useState($count, 0);
  ...
}

Just curious, are React hooks at all inspired by S and Surplus?  There are similarities down to even the names and terminology used.  S has S.effect() and S.cleanup(), and useState() is analogous to S's S.data().
For instance, here's the hooks example in Surplus:
function Example() {
  const count = S.data(0); // S.data instead of React.useState

  S.effect(() => { // S.effect instead of React.useEffect
    document.title = `You clicked ${count()} times`;
  });

  return (

You clicked {count()} times

      <button onClick={() => count(count() + 1)}>
        Click me
      </button>

  );
}

In fact, I used almost this exact same example in the Surplus FAQ to explain how functional components could have state -- the very same issue hooks are solving for React.
I'm the author of S and Surplus, and reading the hook docs gave me a strong case of déjà vu!  The similarities may be coincidental -- we're probably reading the same upstream sources.  But if there was any influence, I thought that would be cool :).

@alqamabinsadiq, sorry if my comment was somehow confusing. This is not how the hook intended to be used, I was making an example of additional effort required for using object destructuring. This is how the correct code looks like:
let [name, setName] = useState('Name')
let [surname, setSurname] = useState('Surname');

Less effort to write, less effort to read.

@adamhaile To my knowledge we weren’t influenced at all by Surplus (this is my first time seeing it). It’s true the “effect” name is similar, but both names are descriptive, so I guess it shouldn’t be too surprising that the names overlap.

@benjamn @spicydonuts If you decide to publish a follow up RFC with named hooks which doesn’t have the conditionality constraints, then be sure to cover other pitfalls that you may also get. In the current proposal there is clearly one thing that will unexpectedly break when you don’t have names. However there are other things that might become confusing too. Such as that an effect doesn’t cleanup and refire when it’s in a conditional. So even with names you might find it best practice to avoid conditionals.

I see what you mean. Hmm.. that's unfortunate :thinking:

I like the idea, but I think the naming doesn't really reflect what's going on here. The term hook in other contexts, such as web hooks or Emacs, implies that something happens at a particular point in time and calls out to some other functions/methods to make it happen.
In the words of the Github docs for Web hooks:

Webhooks allow you to build or set up GitHub Apps which subscribe to certain events on GitHub.com. When one of those events is triggered, we'll send a HTTP POST payload to the webhook's configured URL.

For example web hooks are called whenever Github detects a branch has been created. They're called in Emacs whenever a file is loaded or a particular mode (for syntax highlighting + shortcuts) is activated.
In React, the only hooks I can think of at the moment are the componentDidMount and componentWillUnmount functions, since they're part of a lifecycle and call out to some other function (as part of being overridden in a Component class)
From the React Hooks documentation it looks like these are managers:

useState manages and coordinates state
useEffect manages and supervises side-effects
useContext manages context

Other options for naming:

manager
supervisor
coordinator
handler

I'm sure there are other, better names other than "hook" which can be used.
Also, the naming of the methods don't need to change since none of them seem to have the word "hook" in them, the naming change would just affect the rest of the documentation/examples.

@leebyron, I like your idea! Taking it one step further, we could actually add hooks as an additional argument into function component by React.hooks. It would work in a similar way to React.forwardRef.

What's the advantage of this approach over a HOC-based one such as the one used, for example, in recompose?

@leebyron Conceptually they’re algebraic effects. It just happens that the engine (a pointer to the current “handler”) lives in the react package. Note that the actual implementation doesn’t live in the react-package. So anyone can implement their own dispatcher. Even inside a react render. If this is a popular pattern you could just have a general purpose pattern for this like “dispatcher” package or something.
Just like context there doesn’t have to be one. In multi-threaded environments there can be several.
We considered passing it but then you would have to pass it through multiple layers of indirection. We already know this to be a pain (which is why we have context to begin with) and for something as light weight as custom hooks it is even more so.

@david https://github.com/acdlite/recompose/commit/7867de653abbb57a49934e52622a60b433bda918

@benjamn The this was actually in the first idea and later dropped because it added weirdness and got even weirder when composed with custom hooks. Since they would need to change to a different variable or use .call.

Are there any concerns about the interaction of transpilers with state hooks? The order of function calls could conceivably be rearranged by a transpiler or minifier in a way that differs between an SSR and client-side bundle.

@probablyup I've never seen that any transpilers/compilers move around function calls to different positions, as that would simply break all apps, even without hooks.

It can happen with component folding and such where things are being extracted out of another function.

@sebmarkbage, would there be any recommendations on how to write tests for components that use useEffect()? Should we expect something in jest-react for mocking such things, or that's something that should be implemented by the user?

This API seems to encourage the use of of lambdas as child properties. Wouldn't that cause the children to re-render every time, even if the other properties stayed the same?

@sebmarkbage:

It just happens that the engine (a pointer to the current “handler”) lives in the react package.

Is the expectation that during rendering I might change the pointer to this handler multiple times? It would be great to see the RFC cover what the API for this might look like - especially to make sure it's exposed so that non-internal React renderers can support hooks.

We considered passing it but then you would have to pass it through multiple layers of indirection. We already know this to be a pain (which is why we have context to begin with) and for something as light weight as custom hooks it is even more so.

Can you share a little more about this? I'm not sure I understand the case.
One thing I'm thinking of is custom hooks. Say I want to publish a library that provides useFormInput like in Dan's talk. That library will need a hard dependency on React so that it can access the top level API for useState - however if instead hooks was an argument to useFormInput then it could be free of dependencies. That seems like a strict improvement to me, but I'm curious if there are other examples of indirection where it is painful.
@lexeyraspopov - That holding a reference to the current state is exactly the kind of global state I'm concerned about
@benjamn - I think the idea of this might be semi-toxic for functional components and Flow/TS environments, but it's definitely a convenient way to introduce additional API. Personally, I would prefer a function argument.
@grabbou - This is an interesting idea. React.withHooks((props, hooks) => { nodes }) would make it explicit that hooks are being provided to the component and guarantee additive only API (who knows what people assume for the non-first argument in functional components today). I'm curious, @sebmarkbage, if there's potential performance benefits to knowing apriori that a functional component has or does not have hooks with an API like this?

I'm wondering how we would use this with TypeScript:
const [age, setAge] = useState<number>(42);

Every single project that I see in business I consult for, are using TypeScript, I hope that we will have official TS support from the React team 🙏 it could even be using .js file like Webpack is doing:
 🤞  needless to say I think that a separate @types/react package is really confusing and can create a lot of trouble.

@sophiebits Thanks, yeah, I figured it was most likely parallel evolution.  The pairing of effect and "clean up" was what had me wondering mostly.

When using TypeScript and rendering on the server using renderToString(), I get the following error:
UnhandledPromiseRejectionWarning: Invariant Violation: Hooks can only be called inside the body of a function component.
        |     at invariant (webpack://%5Bname%5D_%5Bhash%5D/./node_modules/react/cjs/react.development.js?:125:15)
        |     at resolveDispatcher (webpack://%5Bname%5D_%5Bhash%5D/./node_modules/react/cjs/react.development.js?:1450:28)
        |     at useState (webpack://%5Bname%5D_%5Bhash%5D/./node_modules/react/cjs/react.development.js?:1473:20)

My HookedComponent is defined below:
const HookedComponent = () => {
  const [name, setName] = useState("Mary");

  return (

{name}

      <input value={name} onChange={e => setName(e.target.value)} />

  );
};

@phil-lgr In that example the explicit type shouldn't be necessary, because of the default argument.

@spicydonuts yes, I'm just hoping that TypeScript usage is on the radar! 👍 Even user writing regular ES6 JS could benefits from first class support for TS.. I can't live without auto-complete in JS anymore.

@phil-lgr I do believe this API will be relatively easy to use with TypeScript, as mentioned in the FAQ.
Perhaps something along these lines?
type SetStateFunction<T> = (
  newValueOrFn: T | ((oldValue: T) => T)
) => void;

declare function useState<T>(initialValue: T): [T, SetStateFunction<T>];

Since there's a restriction to use only actual functions and not arrow functions can't the state manipulation be though a this.setState and this.state?

@ValeriaVG I see no such restriction, is that listed somewhere in the RFC/docs?

@kingdaro https://github.com/reactjs/react-future/blob/master/07 - Returning State/01 - Stateful Functions.js

// The component itself is a single function that accepts props and state as
// arguments and returns a new element. Effectively the render method.
// If callbacks are suppose to do any updates to state (or cause side-effects),
// they will need to be wrapped before passed down. Conveniently, the "this"
// argument will be a function that can be used to wrap callbacks.
// This wrapper is essentially equivalent to:
// function wrapper(fn) {
//   return function(...args) {
//     component.setState(
//       fn.call(wrapper, component.props, component.state, ...args)
//     );
//   };
// }

@leebyron

Is the expectation that during rendering I might change the pointer to this handler multiple times?

A third party can reimplement anything on the dispatcher:
// Current owner should be extracted into a third party peer dependency
let currentOwner = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.currentOwner;

let myDispatcher = {
  useCallback,
  useContext,
  useEffect,
  useImperativeMethods,
  useLayoutEffect,
  useMemo,
  useMutationEffect,
  useReducer,
  useRef,
  useState,
};
export function useThirdParty(callback) {
  let prevDispatcher = currentOwner.currentDispatcher;
  currentOwner.currentDispatcher = myDispatcher;
  try {
    callback();
  } finally {
    currentOwner.currentDispatcher = prevDispatcher;
  }
}

It's not common that you would but you could.
One particular use case we've floated is the ability to render React trees (synchronously) down to values similar to what the Call/Return proposal did. It does this by overriding the dispatcher temporarily in a render so that any nested hooks executed, are properly stored in the right keys etc.
function Foo({ children }) {
  let values = useChildren(children); // recursively reconcile children down to primitive
  // reason about primitives rendered
  return
<OtherComponent values={doSomethingWithValues(values)} />
;
}

Perhaps you recognize this pattern. ;)

That library will need a hard dependency on React so that it can access the top level API for useState

This is true for any dependency. We typically don't do explicit dependency injection of everything. The react package is a pretty small one that we can make smaller too.
The implementation of hooks is literally just a convenience method over useX = (...args) => currentOwner.currentDispatcher.useX(...args) (assuming currentOwner moved out) so it could go into some other package if this actually becomes a problem. Like react-hooks. Or you can just inline that helper in your library. Currently it's not a big driving factor since react-clones tend to fork and alias the react library anyway. Even though the class component base class also has the same dispatch mechanism since it passes an arbitrary "updater".

I'm curious if there are other examples of indirection where it is painful.

It's the same as we don't pass module cache, this etc. It's just an extra argument to everything you do:
function useWindowSize(hooks) {
  let [size, setSize] = useState(hooks, [0, 0]);
  let otherThing = useOtherCustomHook(hooks);
  useEffect(hooks, () => {

  });
}
function Bar({ ... }, hooks) {
  let [foo, setFoo] = useState(hooks, { myInitialState });
  let [bar, setBar] = useState(hooks, props.defaultFoo);
  let x = useWindowSize(hooks);
  return x;
}

vs.
function useWindowSize() {
  let [size, setSize] = useState([0, 0]);
  let otherThing = useOtherCustomHook();
  useEffect(, () => {

  });
}
function Bar({ ... }, ) {
  let [foo, setFoo] = useState({ myInitialState });
  let [bar, setBar] = useState(props.defaultFoo);
  let x = useWindowSize();
  return
}

It gets tedious quickly and then you want dependency injection, which is what the dispatcher is.

Do y'all see a use case for Hooks being used to share logic between Class components? (Perhaps in an interim between converting Class components to Functional components?)

Maybe I'm missing something, my concern with this API is that it lets you write a component that looks like a pure function but actually isn’t. That is, given this line:
const [count, setCount] = useState(0);

Sometimes count will be zero. Sometimes it won’t. It magically changes behavior based on the execution context. With this.state, at least it's clear that it’s tied to class instantiation. As confusing as this and classes can be in JavaScript, those things aren't going away anytime soon. Developers will eventually have to work with those concepts to be proficient in working with Javascript, regardless of the framework chosen.
The possibility of multiple hooks is also likely to be confusing to new developers. This is a somewhat contrived example, but because hooks are order-dependent, this won't work:
function Example(props) {
  if (props.numberCounter) {
    const [count, setCount] = useState(0);
    return (

You clicked {count} times

        <button onClick={() => setCount(count + 1)}>
          Click me
        </button>

    );
  } else if (props.tallyCounter) {
    const [tally, setTally] = useState('');
    return (

Click Tally: {tally}

        <button onClick={() => setTally(tally + 'x')}>
          Click me
        </button>

    );
  }
  return null;
}

I realize you can use a linter to ensure hooks are only used at the top level, but many devs (especially new ones) don't turn on linters by default, so creating this sort of foot gun is ... not great.
I feel a lot of these concerns could be addressed by simply adding an additional parameter to the function. The ergonomics could be tweaked, but something like this is a lot more intuitive IMHO:
function Example(props, { useState }) {
  const [count, setCount] = useState('count');
  // ... same as before ...
}

I really don't want to drop in on the conversation with something unrelated, or already addressed and I missed something. If this is totally stupid, I apologize in advance for the wasted time 😊
Is there more to read about why the render props alternative was discarded? I have played with a solution similar to reactions component, where state is a render prop component (something like
const Foo = () => (
<State
  initialState={{ counter: 0 }}
>
 { ({state, setState}) => (

<input value={state.counter} /><button onClick={() => setState(state => ({counter: state.counter+1}))} />
)
</State>

I know there are drawbacks in this API, with how verbose it is, both in the code and also in the created component tree. But the major advantage I see in this solution is that it lets me focus on the component tree and not on how I've decided to split my component functions. I think that advantage is not available in the hooks API, and it may be worth it to research into solving the other problems with render props instead of a different API. A small example for that could be:
const Foo = () => (

    <State
  initialState={{ counter: 0 }}
>
 { ({state, setState}) => (

 Counter 1
      <input value={state.counter} /><button onClick={() => setState(state => ({counter: state.counter+1}))} />

  )
</State>
<State
  initialState={{ counter: 0 }}
>
 { ({state, setState}) => (

 Counter 2
      <input value={state.counter} /><button onClick={() => setState(state => ({counter: state.counter+1}))} />

  )
</State>

)

In this example my state usage is confined to only the part of the tree that could be affected by each state, and I don't have to split into 2 more components just to get that same level of separation between the two states. This also let's me easily create composable behaviors. Here is an example of a reuseable composition:
export function Resource<T>(props: {
  createResource(): Promise<T>;
  releaseResource?(resource: T);
  onResourceCreated?(resource: T);
  children: Renderable<{ resource?: T }>;
}) {
  return (
    <State
      initialState={{
        resource: undefined
      }}
    >
      {({ state, setState }) => (
        <Lifecycle
          onDidMount={async () => {
            const resource = await props.createResource();
            setState({
              resource
            });
            props.onResourceCreated && props.onResourceCreated(resource);
          }}
          onWillUnmount={() =>
            props.releaseResource && props.releaseResource(state.resource)
          }
        >
          {props.children({resource: state.resource})}
        </Lifecycle>
      )}
    </State>
  );
}

I've been using this API in a project for quite some time, haven't written a class component in quite some time. And my mental model of react stayed the same, no new concepts to learn, it's just components! Maybe I've grown to fond of it to see the drawbacks. I'd love to hear considerations against and be enlightened.

I still have the usual issue with useContext(Context). Passing the context object in order to consume the context, instead of passing the consumer to consume the context.
React's context object has a Provider and a Consumer. However I (and likely others) regularly do not export the actual context object. I often export a custom provider and consider the real provider to be private.
There are various reasons that the Provider may be replaced.
The Provider turns props into an object
Or otherwise the provider has some logic turning props into the value that is provided to context. e.g. making a theme instance out of props.
// foo.js
const FooContext = React.createContext({});
export const Consumer = FooContext.Consumer;
export function Provider({foo, bar, baz, children}) {
  const data = shallowMemoized({foo, bar, baz});
  return <FooContext.Provider value={data}>{children}</FooContext.Provider>;
}

// usage
import {Provider, Consumer} from './foo';
<Provider foo={...} bar={...} baz={...}>
  ...
  <Consumer>{({foo}) => { do something with foo }}</Consumer>
</Provider>

The Provider exports multiple providers
// foo.js
const FooContext = React.createContext({});
const FooContext = React.createContext({});
export const FooConsumer = BarContext.Consumer;
export const BarConsumer = BarContext.Consumer;

export function Provider({foo, bar, children}) {
  return <FooContext.Provider value={foo}>
    <BarContext.Provider value={bar}>
      {children}
    </BarContext.Provider>
  </FooContext.Provider>;
}

// usage
import {Provider, BarConsumer} from './foo';
<Provider foo={...} bar={...}>
  ...
  <BarConsumer>{({bar}) => { do something with bar }}</BarConsumer>
</Provider>

The Provider self-exposes data
// foo.js
const FooContext = React.createContext({});
export const Consumer = FooContext.Consumer;
export function Provider({children}) {
  const foo = 1; // substitute for complex code that may be generating shared context data or providing data that comes from an external source
  return <FooContext.Provider value={foo}>{children}</FooContext.Provider>;
}

Conclusion
For this reason I think things that consume the context should take the consumer instead of the context itself. i.g. useContext(Context.Consumer) so it remains compatible with cases where the Context itself is not exported.
Otherwise if that does not happen, React should officially recommend the practice of exporting custom effects for context usage whenever custom Providers are exported:
// foo.js
const Context = React.createContext(1);
export const Consumer = Context.Consumer;
export const useFoo = () => useContext(Context);
export function Provider() { ... }

@fongandrew Technically making it an argument doesn't make it pure, since reading from useState is still a side effect (and order-dependent, another side effect), but it is much more intuitive and testable.

These are named poorly.
Hooks are a common programming paradigm and what we have here is not a hook.
componentDidMount is much closer to something resembling a hook than this.
Cool feature, can't wait to use it. I think it should be called something else.

@jordonbiondo Well it needed to sound simpler than "[un-typed] Indexed Monads for your component state!" :wink:

@dantman I think best practice will be to expose a custom hook that reads from your context. That way you can also add custom logic to that hook in the future.

@fongandrew I'm with you in your concern about order-dependence, and I also agree with the direction of your solution.
Providing meaningful names when calling hooks would allow them to be called from anywhere. The precise API is important, and perhaps there is no perfect API for this kind of naming, but that would be pretty surprising to me. The status quo is a strange rule-of-thumb enforced by a linter, so I think there's a decent chance we can do better.
Also, full disclosure: despite my Member-ship in this repository, I am not a representative of the React team. They've got the final say, and I can only try to persuade them.
I think the team will say it would be burdensome to pass names into custom hooks that compose other hooks, and that it would be risky to call useState(name, initialState) from two different custom hooks with the same name, because they'd be mistakenly referring to the same state.
I'm still working through the details like everyone else, but I don't think this objection stands. The name wouldn't just be a single string, possibly duplicated between custom hooks. The names would be contextual, unique within the context of a custom hook function or functional component, so two calls to useState with the same name from different custom hooks would remain distinct, rather than colliding with each other.
Of course, this means custom hooks can't just be simple functions, and would have to be invoked in a special way that temporarily establishes the necessary context. But that's essentially what happens with functional components already; it's just that the React rendering internals establish the context in which the functional component gets invoked.
If this same layering of contexts happened with custom hooks as well, then I think naming could become a powerful tool for referring to specific hooks, and for disambiguating hooks, without any need for a linter. Only the author of the custom hook would need to worry about establishing a context for its children. No one calling the custom hook would have to think about that nuance, ideally.
As I promised above, I'm hoping to open an issue that proposes this naming feature sometime today/soon.

Isn't this achievable in user-land (without touching React) say, using generators:
hook(function* Example() {
  const [count, setCount] = yield useState(0);

  return (

You clicked {count} times

      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>

  );
});

@lmatteis I proposed something like that here: https://github.com/reactjs/rfcs/issues/29

Loving it (there i said it).
One question, is this the only (or proper) way to use a default value with useReducer?
  const [count = initialCounter, dispatch] = useReducer((state = initialCounter, action) => {
    debugger
    switch (action.type) {
      case "INC":
        return state + 1;
      case "DEC":
        return state - 1;

      default:
        return state;
    }
  });

@lmatteis @streamich
These kinds of features are also already possible in library-land using observables via Refract - also means using general-purpose primitives rather than a DSL 😄

@sebmarkbage thanks for the additional info - super helpful to understand the thought process.

A third party can reimplement anything on the dispatcher

I also want to use without being fired ;) - I appreciate that these top level functions are syntactical convenience and that overriding their implementation dynamically is possible. That's enough to calm most of my fears of the global, though I'd hope that the mechanism for doing so will become a little less obfuscated as the API matures.

It gets tedious quickly and then you want dependency injection, which is what the dispatcher is.

I guess I just don't see this getting tedious. As a quick example:
function MyStatefulComponent({ myProp }, { useState }) {
  const [ myState, setMyState ] = useState()
  return ...
}

A component like above is nice to see which hooks it uses directly and this doesn't feel all that tedious to me compared to importing useState from React directly. In fact, most of my functional components currently don't require the React package at all and needing hooks will require them to do so where passing in the hooks would not.
Using custom hooks would require passing hooks as an argument, but that feels like it actually makes explaining this concept easier.
Globally accessed:
// A.js
const { useEffect } = require('React')
module.exports = function useCustomEffect() {
  useEffect(() => doSomething())
}

// B.js
const { useState } = require('React')
const useCustomEffect = require('./useCustomEffect')
module.exports = function MyComponent({ myProp }) {
  const [ state, setState ] = useState()
  useEffect()
  return
{state}{myProp}

}

Accessed from a "hooks" second argument. Perhaps hooks can have a hooks self-ref property to allow for easier destructuring:
// A.js
module.exports = function useCustomEffect(hooks) {
  hooks.useEffect(() => doSomething())
}

// B.js
const useCustomEffect = require('./useCustomEffect')
module.exports = function MyComponent({ myProp }, { useState, hooks }) {
  const [ state, setState ] = useState()
  useEffect(hooks)
  return
{state}{myProp}

}

IMHO the latter is less tedious and perhaps a bit easier to explain

i can't use the useState() feature i my project. when i create the app with yarn create react-app myapp command, i go in the root directory of my project and i modify the react version in my package.json from<EMAIL_ADDRESS>to<EMAIL_ADDRESS>and after i do yarn install.
but when i try to use the example below it doesn't work :
function App() {
  const [count, setCount] = useState(0);
  useEffect(() => {
    document.title = `You clicked ${count} times`;
  });

  return (

You clicked {count} times

      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>

  );
}

I get this error :
TypeError: dispatcher.useState is not a function
useState
node_modules/react/cjs/react.development.js:1502
  1499 |
  1500 | function useState(initialState) {
  1501 |   var dispatcher = resolveDispatcher();
> 1502 |   return dispatcher.useState(initialState);
       | ^  1503 | }
  1504 |
  1505 | function useReducer(reducer, initialState, initialAction) {
View compiled
App
src/App.js:3
  1 | import React, { useState } from 'react';
  2 |
> 3 | function App() {
  4 |   // Declare a new state variable, which we'll call "count"
  5 |   const [count, setCount] = useState(0);
  6 |
View compiled
▶ 22 stack frames were collapsed.
Module../src/index.js
src/index.js:7
   4 | import App from './App';
   5 | import * as serviceWorker from './serviceWorker';
   6 |

Please, How create an app with the version of react that contain the new Hook feature ?

@emmadal You need to upgrade react-dom to the same version as well

@jtmcgrath It allows on the client but not on the server.

what version of react-dom i must installed ??

For those curious, Suspense and Hooks work together beautifully.
import React, { Suspense, useState } from "react";
import { unstable_createResource } from "react-cache";

const exampleResource = unstable_createResource(
  value =>
    new Promise(resolve => {
      setTimeout(() => resolve(value), 300);
    })
);

function Example({ initialValue }) {
  const [value, setValue] = useState(() => exampleResource.read(initialValue));

  return (

{value}

      <input
        type="text"
        value={value}
        onChange={event => setValue(event.target.value)}
      />

  );
}

function App() {
  return (
    <Suspense maxDuration={300} fallback={
Loading...
}>
      <Example delay={1000} initialValue="Hook and Suspense!" />
    </Suspense>
  );
}```

@arianon shouldn't that be useState(exampleResource.read(initialValue))? Otherwise your state's initial value will be a function, no?

I share a lot of the fears in this thread about relying on an implicit execution context. Instead of relying on this, which is awkward in JS to @sebmarkbage's point, can we pass the execution context as the first value of a functional component similar to @leebyron's suggestion? The context could be then easily threaded to custom hooks. For example:

@jetpacmonkey Nope, passing a function to useState will make it lazily initialize so that the initial value is evaluated only once, very useful for expensive functions. But since calling the .read() method of a resource multiple times isn't expensive, because the result of the promise is already cached. I realize now that it's unnecessary to use lazy initialization, and it can sometimes bite you back once you need cache invalidation.

Hi there,
I suggested a new addition / different RFC similar to this here, but I was directed here.
Do you see any value in expanding this to an "affect" like API that allows hooks for controlling props being passed to child components via render props like uses such as Context?
See original post for more detail.

I've been working on creating tons of hooks for everything you could ever want with a bunch of other folks over here: https://github.com/rehooks
One thing that's come up like 10x already is people not adding the second arg to useEffect & fam, causing their code to re-run on every re-render without knowing.
What if the args were switched around and to subscribe to everything you had to pass a special non-array value:
// always update
useEffect(true | null | false | whateverReactChooses, () => {
  // ...
});

useEffect([...values], () => {
  // ...
});

This would force developers to think about it first

@dantman, @sebmarkbage : I have the same concern over needing to supply the entire context object to read from.  In my case, I'd potentially like to allow a React-Redux user to render <Provider contextProvider={MyCustomContext.Provider}> somewhere in their tree, and then render a <ConnectedComponent contextConsumer={MyCustomContext.Consumer} />.  I can certainly imagine cases where the entire context object isn't available for use there, just the consumer.
Given that a Context.Consumer currently appears to mostly proxy its behavior back to the underlying context object, what's the reason for not accepting it as a valid argument to useContext() ?

I'm going to echo a sentiment that a couple of others[1][2] have mentioned here earlier, because it's worth repeating. Hooks are an existing concept in computer programming and what is being proposed here is not a hook, detour, or trampoline.
Please consider renaming this feature to avoid terminology fragmentation, or elaborate on what React developers mean by "React Hooks" (and not hooks from traditional nomenclature). Creating React-specific terminology makes it harder for new developers to quickly grok what concepts are being discussed.
[1] https://github.com/reactjs/rfcs/pull/68#issuecomment-433155455
[2] https://github.com/reactjs/rfcs/pull/68#issuecomment-433179524

I agree with you @leebyron. Another advantage that I see in your solution is that it's going to be easier to test custom hooks because they wont be dependant on React.

Is Redux and React-Redux going to be replaced by useReducer hooks ?

@contractormario Redux provides more than just what useReducer offers. useReducer just seems to be useful for the subset of use cases where you need more than just state but don't actually need redux and have to setup all of redux just to get a little bit of it.
I do however expect that useContext could actually make it easier for react-redux to switch to the new context system.

Is Redux and React-Redux going to be replaced by useReducer hooks ?

The redux middleware is also still a big part of why you would want to use Redux

@dantman : you're exactly right, on both levels :)  Redux does have benefits that hooks, nifty as they are, don't cover.
And yes, I'm playing around with converting one of our existing React-Redux v6 WIP PRs to use hooks internally instead of class components, and it looks way simpler now :)

I'm really exited about this api  🔥. I agree that passing the hooks as an argument instead of relaying on the global context is a lot easier to understand and test. My favorite thing about explaining some react piece to someone is saying "hey this is just JavaScript, no framework magic here". I'm afraid I can't say the same about hooks in the current form.

Pretty sure most of the React team is so busy they won't get to moderate this issue much. But just as a reminder:

⚠⚠⚠ PLEASE STAY ON TOPIC ⚠⚠⚠
This discussion should  be focused on the design and implementation details of this RFC
Other discussions (including ones related to this RFC) and question should go to Reactiflux or Twitter

React team can feel free to delete this comment if they feel it unnecessary, just didn't want this thing to get out of control when you're supposed to be having a good time at ReactConf

I read the entire docs about Hooks after pure excitement. Not having to manage changed props in componentDidUpdate feels like a lifted burden already :) The thing which is going to be less clear for newcomers not reading the docs will be the empty array as the second argument to useEffect.
Which will only trigger it on mount and unmount, this is way more explicit in the current Class components.
With the new Hooks, "You just gotta know".

Yay, I'm very excited for this for my personal projects!! Just last week I was pretty frustrated by deep nesting from small render-prop components, and I'm excited for the opportunity to flatten those out at the top level :D Thanks for working on this!!
I'd love to use hooks for solving "wrapper hell" and complex-components at work, too. But I think we might not be able to, because hooks seem to require us to be all-in on other major changes, too 😓
I'm very interested in the new state idioms, improved lifecycle model, and implicit ordered storage! I think they're neat ideas and potentially the future, and I'm glad we're exploring them!
But we already have onboarding issues at our company, so the fragmentation cost of using new paradigms in new code just seems like too much to handle, especially for a team with lots of junior folks 😓

Do you have any advice for a team that wants the encapsulation and composition wins of hooks, but isn't ready for the other paradigm shifts?
Maybe there could be an alternate syntax that's closer to existing React component classes? If we could write custom hooks using setState and componentDidUpdate, that would be a game-changer in terms of enabling our team to adopt.
Similarly, maybe there's a path forward for using hooks inside class components too, so that we can leverage hooks in old code without refactoring? 🤔 I wonder if it makes sense to eventually allow them to be called from render methods, like in functional components?
Anyway! Overall, I'm very interested in moving our company toward hooks, but I think we'd need an even more incremental adoption path in order for it to be a good choice for our team. I hope that's a possibility—thanks for considering!!

One of the things I personally like recompose's setState is how it turns state into props for the wrapped component.  Once you're inside the wrapped component, you no longer have to think about where those props are coming from. This makes it really easy to flip back and forth between state strategies (e.g. redux or component state) as I work on my codebase.
The hooks version is nice in the sense that I don't have to bother will all the gotchas of classes and this.setState, but it still forces the component to choose where the state lives in the same place where rendering is being done.
Passing the state in as props makes it easier for me to separate state and render which is something I like.

Would React also expose an API for "sandboxing" components, and being able to control hooks outside of a normal render, ie tests?
It would be great if some sort of mocking will be a part of React, not outside of it.

I've been experimenting with rxjs and subscriptions. Take a peek.
useStream gist

const useStream = initialState => {
  let source = isObservable(initialState)
    ? initialState
    : new BehaviorSubject(initialState);
  let currentState;
  source.subscribe(val => (currentState = val)).unsubscribe();
  let [value, setValue] = useState(currentState);
  let [subject] = useState(source);
  useEffect(() => {
    let sub = subject.subscribe(setValue);
    return () => sub.unsubscribe();
  }, []);
  return [value, subject.next.bind(subject)];
};

it doesn't work with the fat arrow function. why ?

Others have brought up the issue of order-dependence.  Adding a name parameter to useState would avoid order-dependence but would make the syntax more verbose (and would introduce the new problem of name collisions).
So here's another idea.  React already has a solution for verbose React.createElement syntax: JSX.  Could syntax be added to JSX which generates a unique tag for each call to useState based on its source location?  Source locations are unique, so there can't be name collisions.  And each location is statically-defined, so dynamic changes to the order can't affect them.
I don't feel knowledgeable enough about React to propose any specific syntax, and maybe you've already thought of this, but I think it would fix the biggest problem with this (otherwise great!) proposal.

Is it advisable to do something like this. Its basically the render props pattern without the weird prop/function, which makes it easier to understand.
import React, { Fragment, useState } from "react";

import useCounter from "./counterHook";

export const App = () => {
  const { counter, incrementButton, decrementButton } = useCounter({
    inital: 0,
    max: 5,
    min: 0
  });
  return (
    <Fragment>
      <span>{counter}</span>
      <h2>Some other markup</h2>
      {incrementButton}
      {decrementButton}
    </Fragment>
  );
};

counterHook.js
import React, { useState } from "react";

export default function useCounter(
  { inital, max, min } = { initial: 0, max: 10, min: 0 }
) {
  const [counter, setCount] = useState(inital);
  const incrementButton = counter < max && (
    <button onClick={() => setCount(counter + 1)}>+</button>
  );
  const decrementButton = counter > min && (
    <button onClick={() => setCount(counter - 1)}>-</button>
  );

  return { counter, incrementButton, decrementButton };
}

I think this RFC undermines one of the arguably fundamental aspects that makes React great: Simplicity. I am not sure adding any more APIs are justified by the rationale outlined.
For most of the problems outlined in the Motivation seems like the consequences of other problems, lack of understanding of JavaScript, over complicated components (requiring reuse of logic and the issue outlined as "Complex components").
I think all those problems could be solved with better patterns that does not involved increase the React API surface and introducing what seems like magic.

First of all, awesome job! I absolutely enjoy using react every day, and it's all credit to your hard work.
The API is quite succinct and will probably be easy to pick up. A few things I've noticed:

At a first glance, the signatures of hook functions look to be indistinguishable from non-hook functions.
There are a few quirks with the API which will lead to surprising things (like you can't use a hook inside an if statement)

A monadic interface would alleviate the above oddities. An understanding of monads wouldn't be necessary for use (I used promises for a long time without an understanding of monads).
In practice, this would look something like:
useState(0).map(([count, setCount]) => {
  return <div>{count}</div>
})

useState would return a ReactHook<[number, number => void]>, which is a type that encapsulates that:

It is a react hook
The value inside is an array with state + management.

To compose ReactHooks you could simply use the monadic chain:
const withTwoState =
  useState(0).chain(outer =>
    useState(15).map(inner => {
      return {
        outer,
        inner
      }
    })
  )

With this example:

The signature of useState is meaningful.
It's straight forward when/where you can use branching logic.

@pfgray that doesn't win much over nesting render props then

@VinSpee , good point!
There are many techniques for reducing the nesting of monad chains, such as:

Do
Generators/Coroutines (although not the biggest fan)
Syntax sugar (Likely far from being included in the language)

In my opinion, a monadic interface would be quite forward thinking. Not sure if there is enough information disseminated to enable people to hit the ground running, though.
here's an example of using 6 nested render props with Do,
and
here's an example of what it looks like with syntax sugar

@pfgray isn't the Do syntax then not much different from HoCs?

@VinSpee, with HoCs you don't have a reference to the previous value (values are passed implicitly via props), but with Do you do & can name the parameters anything you want.
Here's an example using Maybes that shows this. Each "step" has the values from previous steps passed in as parameters & you can name them however you'd like.

I am wondering how this feature can fulfill a dynamic injection of state, for some future state is not available until some future-triggered action. Is this hook taking care such dynamic scene?

My first thought looking at this API (besides wow, this is cool and convenient) is that it looks way too magical. I can only call react hooks at the top level of the function lest I mess up the order dependency. It all makes sense, but it feels like a function call inside the component render body is the wrong abstraction.
Were any less magical alternatives considered? An HOC could work well for this, or even a component that exposes state and setState via render props.

@benwiley4000 They explain this in the RFC: https://reactjs.org/docs/hooks-intro.html#its-hard-to-reuse-stateful-logic-between-components

Ah sorry, I missed that. I guess I follow the reasoning mostly but I'm not convinced this is a better pattern.

awesome job! but I am wondering how this feature can fulfill a dynamic injection of state. As part of app state grows unpredictably, some states would be added asynchronously from the future actions of user. Are the useState/useReducer hooks really taking care of those dynamic scenes?

I love the direction here!  Thanks so much for your hard work on this React team! ❤
I definitely agree with @leebyron 's comment a ways back in the thread about bringing in the hooks as a second argument to the function.  Doing that would keep the "component as a pure function" feeling intact, and could also make mocking your hooks super simple in tests, as you no longer have to mock the import of the hook from react.
This feels really nice to me:
import React from 'react';
export default function ClickCountingButton(props, { useState }) {
  const [count, setCount] = useState(0);
  return <button onClick={ () => setCount(count + 1) }>clicked { count } times</button>;
}

It's cool to see this new idea/pattern, but I have to agree with @omeid. I fear it brings little benefits in terms of being able to do something new (or really even something that much simpler) while it continues to expand the surface area of React, making it increasingly difficult for newcomers and experienced devs alike to figure out what's going on. If the goal was to eventually switch away from classes to this pattern I don't think I'd mind too much.
Maybe I missed something, but, imho, nothing in the RFC gives good reason as to why this is truly needed in the first place. I don't think escaping "wrapper-hell" is worth the added learning curve.

I think adding such an api with an option in the dev tool is enough to solve "wrapper hell"?
import { hiddenDefault } from 'react'

const FooComponent = /* ... */
FooComponent[hiddenDefault] = true

At a first glance this looks like a really neat way of reducing some of React's inherent verbosity, and dramatically reducing the depth of the component tree - I'm very excited about both of these.
One question though: will this cause idiosyncratic behaviour during development with hot reloading (e.g. if a dev inserts a new useState hook in the middle of a bunch of other hooks)?

@alqamabinsadiq here i think that the setState  must not to be use because the component is created from keyword function. this feature eliminates component creations by creating class and using setState. but you can always create your component it work always but if you create your component with the class you must use setState but if it's with function you must use the Hook

@emmadal It's working for me and it's similar to the on we use in classes but now I do the same thing with above code in functional component. Test it out it will work.

It’s hard to reuse stateful logic between components.

I feel like this point could be better solved by both allowing arrays as lifecycles/events and allowing these to return objects to update state i.e:
class A extends Component {
state = {value: 'Mary'}
componentDidMount = [UseHook2, UseHook3]
componentDidUpdate = [UseHook2, UseHook3]
componentWillUnmount = [UseHook2, UseHook3]
handleEvent = [UseHook1, UseHook2]
}

const UseHook1 = (e) => {
return {value: e.target.value}
}
const UseHook2 = (...args) => {
return {...}
}

//...etc

Especially now that class fields are effectively making it into the language.

From this example:
export default (() => {
    let [count, setCount] = useState(0);

    if(count <= 2){
      useEffect(() => {
        console.log(count);
      });

      /* if enabled, will error because less hook executed on else clause*/
      /*
      useEffect(() => {
        console.log("1st" + count);
      });*/
    }
    else{
      /* if not subscribed, will error because less hook executed on this condition*/
      useEffect(() => {
        console.log("2nd " + count);
      });
    }

    return <div>
      <button onClick={() => setCount(count + 1)}>Click Me</button>
    </div>;
});

It seems that useEffect makes react subscribe the effect event every time it renders, and the fact that code above is fully possible really concerns me. Why don't stick with HOC and improve it to reduce wrapping hell?

@jaredLunde

@JoshuaKGoldberg How would you customize those object properties? Array is the cleanest way it works with custom naming.

const counter = state(0);
return (
  <>
    <button onClick={() => counter.update(x => x - 1)}>- 1</button>
    {counter.value}
    <button onClick={() => counter.update(x => x + 1)}>+ 1</button>
    <button onClick={() => counter.reset()}>reset</button>
    <button onClick={() => counter.set(10)}>=10</button>
  <>
);```

Isn't this a class purpose to have a state and manage it?

first of all great work React Team. really enjoyed the keynote.
I am not sure if it has been asked before.
thinking about a functional component first thing that comes to my mind is that there is no control over the re-render. state or props change. it will simply re-render. that was ok until we had no function declarations inside this functional component. but now we have function calls, declarations inside a simple functional component which will be called multiple times. doesn't that re-initialize all the variables, function declerations, event handlers that we would  be in there ? isnt that bad for performance ? i am sure hooks will have some performace fix for this kind of problem. but our custom function declerations will not. unless i declare them outside the function which makes it a bit more complicated i guess.

my 2c:
I hear the arguments about increased surface area and this is something I mentioned to my colleagues when I saw this for the first time. I can understand those arguments and in part agree with them.
I also think that in order to have any kind of half decent React application, you need to know a lot of things that aren't React and/or know the perfect way to organise your components which only really comes with experience of working in React (and it's still really easy to shoot yourself in the foot).
I see this API more approachable for beginners as it solves a problem that React (and Node in general) has had for the past few years: It makes a few sane decisions for you and helps you do The Right Thing and then gets out of your way. While the size of the API has increased, I think this API reducers the burden of knowledge on beginners and also makes writing React frankly less tedious.
This is to say nothing of the benefits that this simpler API would have for TypeScript - Using decorators in TypeScript is something of a nightmare at the moment if you want to go for type safety. It would be much easier to write React in a type safe way with this API.

@hannadrehman
https://cdb.reacttraining.com/react-inline-functions-and-performance-bdff784f5578
https://reactjs.org/docs/hooks-faq.html#are-hooks-slow-because-of-creating-functions-in-render

It'd be great if support for Typescript was not an afterthought but designed in. For example there should be some way to have a type-safe, generic useState with Typescript. Maybe this can be made to work already with the current design?

@newtack there is a section on type safety in the RFC. One could have a typesafe use state with this definition:
declare function useState<T>(initialValue: T): [T, (newValue: T) => T]

React Team congratulation for this work! Finally the problematic decision for every component - "should it be a class or a function" will be over.
My concern is here the naming. I just don't see useful -> use prefix. My proposition here is to keep it in own namespace, but without any additional prefixes or suffixes. Take a look:
import { hooks: { state, effect} } from 'react'
const [age, setAge] = state(42);

@maciejsikora

My concern is here the naming. I just don't see useful -> use prefix. My proposition here is to keep it in own namespace, but without any additional prefixes or suffixes. Take a look:
import { hooks: { state, effect} } from 'react'
const [age, setAge] = state(42);

I'm afraid it's not possible to remove "use" prefix. See last 2 paragraphs here. So it's not only about the naming, but also about making other tools (like linters, code formatters etc) working in a desired (configurable) way.
Also, a similar convention is used for HOCs - starting with "with".

Just my two cent, but I would prefer it if the new API was more explicit.
If everything needs to be in order to work, why not mirror it in the API?
React's unidirectional data-flow is a very explicit approach compared to the two-way-binding of other frameworks, it would be nice if that was the case with hooks too.

I've noticed a weird issue with the useEffect and all related hooks currently work.
If the main passed to this hook is an async function, the returned cleanup function never gets called. Here is an example where I was running into this issue.
const [jobs, updateJobs] = useState([])
const [loading, setLoading] = useState(false)
const controller = new window.AbortController()
const signal = controller.signal

useEffect(async () => {
  setLoading(true)
  const res = await fetch(`https://myapi.com?search=${location}`, {signal})
  const jobs = await res.json()
  updateJobs(jobs)
  setLoading(false)

  return () => controller.abort()
}, [location])

It's totally possible that I've missed something, but it would be nice if we could use async/await functions in hooks

Just wanted to give my 2c on the fact that the documentation is absolutely phenomenal. Good job guys!

I feel like I ought to add here a couple of thoughts: It feels like the "order" of useState is a potential foot gun, and using a linter to enforce that seems like a very roundabout way of dealing with ordering dependencies (function arguments). Additionally the custom memoization of useEffect seems odd given, if useEffect was lifted out of the component, it could be a plain function which could be memoized in user land.
I mentioned this to @gaearon this morning and the two issues seemed to be around sharing data between hooks and and name space collisions. I feel like these are both solvable (although I appreciate there may be plenty of implementation / future API areas that I'm missing).
I wonder why the API doesn't use things like plain function and function argument order to handle some of these problems in a way that is more idiomatic JS something like the below (note, this isn't prefect I'm sure but the point is the threading of data more than the exact API).
const Comp = (props, [counter, setCounter], [name, setName]) =>
;

// hook(...stateful)(...effectful)

/*
* statefules have access to props (and maybe the previous state?), reducers could be here too
* effectful has access to access to all states and props and can be memoized in userland
*/

export default hook(props => useState(0), props => useState("Rich"))(
  myMemoize((props, counter, name) => {
    CountAPI.setCountsForName(counter, name);
  })
)(Comp);

Let me be clear, I really like the direction but a lot of these changes feel like the could be implemented using more explicit / idiomatic JS, while still being relatively terse. I'm happy to be corrected or pointed into areas of the API that this doesn't map on to! But Here is my C in the RFC!
Thanks again for all your hard work and innovation 👍
https://gist.github.com/RichieAHB/61fb286d113a59f038ea9c20e66f2146

@RichieAHB - Perhaps I'm misunderstanding, but I don't think you could have cooperative hooks using that approach? For example, a useEffect hook that relies on the value from a previous useState hook. Also not sure what custom hooks would look like.

@jamiewinder in the above examples the effectful handlers are being passed the results of the stateful hooks in the arguments to the function after props - perhaps that's not clear!
// the second two args here
myMemoize((props, counter, name) => {}

@ThePaulMcBride that's because async functions return promises. there would be no way for react to do cleanup here unless it awaited the return promise in the event that it might be a cleanup function (and in the majority of cases it wouldn't be)

Thanks @danpantry. I played around a little more and figured the best approach was to abstract the async code into a separate function and call that in useEffect. That makes the whole thing more testable anyway!

I'm getting this error: Uncaught TypeError: dispatcher.useState is not a function
This is the useState sign:
 useState ƒ useState(initialState) {
      var dispatcher = resolveDispatcher();
      return dispatcher.useState(initialState);
  }

And this is my code:
import React, { useState, useEffect } from 'react'
import ReactDOM from 'react-dom'

function App() {
    const [count, setCount] = useState(0);
    useEffect(() => {
        console.log("rerendered!!")
    })

    return (

 setCount(count + 1)}> Count: {count}

    )
}

ReactDOM.render(<App />, document.querySelector("#app"))

Of course, react version: 16.7.0-alpha.0

The document makes you feel like componentDidMount and other class life-cycle methods are an over-complication and useEffect is so cool and simple. You always could add componentUseEffect for classes, but that wasn't made on purpose.
Also, I must say that the document is huge! That is definitely not a good sign.

@kidandcat Check your react-dom version, I had the same issue. react-dom must also be 16.7.0-alpha.0.

@omeid Fiber and createContext were the plumbing that made this possible, and the former was released over a year ago. Why didn't you and others like you ask this question then?

There two thing the seem to be concerning to a lot of people.
If you think that the requirement of useState() calls to be in the same order between renders is some sort of "foot gun", you should try to write a function that shuffles its variables declaration every time you call the function. It takes some effort to actually do it, especially since we all use block scoped variables these days (let, const). That is not what you would intentionally write in a generic component of your system.
The way how state setter triggers re-rendering or "where state is saved" is concerning people that may not familiar with Fiber architecture. It all starts to make sense after you understand how a function component works with its fiber. I'd recommend watching @aweary's talk from React Rally: https://www.youtube.com/watch?v=7GcrT0SBSnI. It covers the basics pretty good.

React Hooks is awesome!!
https://codesandbox.io/s/6joj6kx3zr

@alexeyraspopov with variable declaration you don't have hidden state. I think this is the major problem.
If order is needed for it to work, let's think about an implementation that forces order.

If you think that the requirement of useState() calls to be in the same order between renders is some sort of "foot gun", you should try to write a function that shuffles its variables declaration every time you call the function. It takes some effort to actually do it, especially since we all use block scoped variables these days (let, const). That is not what you would intentionally write in a generic component of your system.

I think this makes sense but I feel if there is a mechanism to remove that, then why wouldn't you? I also think there are some very easy ways to break the ordering without linting, some of which are outlined here: https://reactjs.org/docs/hooks-rules.html
It's true that it should be easy to spot these issues but I think you can enforce hooks being called at the "top-level" using existing patterns.

I love this API, and I'm especially excited to write (fully testable) IO components without using HOCs or render props:
export default function FriendListLoader() {
  const { data, error, loading } = useQuery('/api/friend-list');

  if (loading) {
    return <Loading />;
  }

  return error ? <Error /> : <FriendList data={data} />
}

@hen-zone Absolutely. Data fetching, especially when you need to transform API responses, can all be neatly tucked into a custom hook:
function useApi(endpoint, selector) {
  const [state, setState] = useState(null);

  useEffect(
    async () => {
      const response = await fetch(endpoint);
      const data = await response.json();
      if (response.status === 200) {
        setState(selector(data));
      }
    },
    [endpoint]
  );

  return state;
}

function App() {
  const quote = useApi(
    "https://got-quotes.herokuapp.com/quotes",
    response => response.quote
  );

  return <>{quote ||
Loading...
}</>;
}

The new API seems to work well! Small note: should useRef be of type T | () => T, like useState is?

@alexeyraspopov, that's a straw man. The requirements are more strict, e.g. you need to have the same number of calls, so loops and conditionals are not allowed freely. Writing loops and conditionals that you call functions from for side effects is completely normal. Talking about variable declaration is a strawman, because everyone acceps they are in the same order.

The pattern of returning a function that is called on cleanup seems a bit confusing to me - it's easy to understand without knowing the pattern or after consulting the docs. What's the argument for this against for example passing an argument to the function?
  useEffect(({mounted}) => {
    if (mounted) {
      ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    } else {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    }
});

Onestly i do not like at all this new hooks, and the philosy behid.
I think React is looking at past and not at future.
Reading that ES6 classes and "this" may be a problem in 2019  it's something that you do not expect from a Team like React one.
Put in the mind that you will not create better JS developers removing "this",
you will CONTRIBUTE to the grow of developers that do not have ideas neither of closure nor of classes & this.
Finally, do you really belieave that closure vs classes is the future? are you serious? Mah.
Anyway a version of func comps like these
Example(props, ownContext)
//smaller version
`Example(props, { context, state={ count: 0 }, setState, onDidRender}){
onDidRender(()=>{
//run side effect
return ()=> cleaner if needed
})
const { count } = state;
return
<>
{count}
setState({ count:count+1)} />

}
`
//extended version if needed
`
Example(props, { context, state={ count: 0 }, setState, onDidMount, onDidUpdate, onUnmount}){
onDidMount(()=>{
})
onDidUpdate(()=>{
})
onUnmount(()=>{
})
const { count } = state;
return
<>
{count}
setState({ count:count+1)} />

}
`
would have been more clean and readable without need of crazy hook excecution rule,
and could be a really alternative of classes.
Regards,
Salvo

I have misgivings about the order of the calls mattering because there are engineers that don't read manuals and don't use tooling with linting setup.
I notice that there are some invariants configured for common mistakes and this is good, since at least it provides some form of guardrail. However, I tried to change the order of a useState and useEffect call and I noticed that in a few cases it gave me no invariant error or runtime error, but occasionally it blew up with TypeError: arr2 is undefined from within a inputsAreEqual function. Similarly, if I switched the order of a useState(0) and useState('hello') within a counter app, it would occasionally blow up with NaN errors (or in fact not blow up but just render strange data).
I think the system should be such that you can detect mistakes like this at runtime and give sensible error messages. You should not be depending on the existence or infallibility of a linter. Runtime errors like the one's I've just described are likely to be difficult for beginners to debug.
If there was a reasonable way to completely avoid this problem it would be good, however I recognise that you wish to create an elegant API. Still, debuggability and sane error messages are important.
Also, I do not feel reading the documentation gave me a good mental model of what state you are storing when I call the hooks and how you expect me to program. Why are all of the functions defined inline? Would it be problematic for me to hoist the functions I pass into useEffect? Is useEffect(getEffectDependingOn(prop.type)) as harmful as a more obvious conditional?

I also have concerns about introducing order-dependence/implicit indexing, and want to highlight a suggestion made by @TrySound on twitter that I haven't seen in the discussion here, as it seems to solve the issues in a much more elegant way than explicit passing of keys/symbols.
Imagine that a useState function with the following signature exists internal to React:
declare function useState<T>(key: symbol, initialValue: T): [T, (newVal: T) => void]

It works exactly as the useState described in the RFC, but using the explicit key to read/update state instead of an implicit index (based on call order). Passing the keys around would be annoying and possibly error-prone (as pointed out by @sebmarkbage).
So instead: react would export this function:
export function createStateHook(debugName) {
  const key = new Symbol(debugName)
  return (intialValue) => useState(key, initialValue)
}

So the key exists, but it's hidden from React consumers. Usage would look like this:
import { createStateHook } from 'react';

const useCounter = createStateHook();

function Example() {
  // Declare a new state variable, which we'll call "count"
  const [count, setCount] = useCounter(0);

  return (

You clicked {count} times

      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>

  );
}

IMO this is the best of both worlds: less restrictions on hook usage, with no extra verbosity. I also think that createStateHook (and createEffect etc.) make a nice parallel to the new createContext API. It's a lot easier to understand that you don't want to call these functions during render, but only in top-level or application setup code.

I don't feel like this achieves the goal of making it easier to use state and lifecycle methods without writing a class.
I was excited to hear about hooks because I thought y'all were just adopting the way InfernoJS does it, where you can just do:
const MyComponent = props => { /* stuff */ }
MyComponent.componentDidMount = () => { /* stuff */ }

This fits in very smoothly with typical developer experience, which with React right now is

I have a pure functional component I've had in my codebase for months and it needs some new functionality
Oh no do I need to add state to this
Agh and it also needs a componentDidMount
So much typing whyyyyy
Okay fine
class MyComponent extends React.PureComponent {
Lots of deleting and copying and pasting and hitting of Tab to reformat everything
I wish I could have spent 2 minutes on this change but I spent like 10 fighting with my text editor

That happens all the time and it's what hooks would be great for, but this is creating an entirely new API instead of leveraging the existing class-based methods. Why the added complexity? Why the need to do something super clever? Why not just adopt Inferno syntax and call it a day?

Is there any plan that ShallowRenderer supports Hooks API?

I am pretty dubious about the consolidated value of this proposal. For what I understand the motivation behind it is mostly syntactic. We are not adding any capability to React here. We are replacing classes with procedures. We are also replacing functions with procedures and calling all that a progress. By doing so, we are mixing javascript with React script as the semantics of these functions became reliant on complex React magic as much as javascript.   Obviously when the going gets tough, people will have to master that magic. And React who was at a terrific advantage vs. other frameworks because it was SIMPLE, is growing incidental complexity in exchange of speculated developer experience.
What is completely missing from the Hooks documentation is HOW DO YOU TEST THIS THING? As mentioned, all this seems optimized for developer experience in the writing phase, but what about the maintenance? the testing? the debugging? That takes way more time. I am really curious about this, because adding closures all over the place, and renouncing to pure functions, we are loosing properties.
In short this is akin to emulate algebraic effects with javascript. and paliating the lacking of the language by adding a second interpreter and runtime in the middle. That simplifies the syntax (well, till a long list of exceptions end up emerging and you end up having to master two languages and two runtimes). I want to know and people should know at the price of what else.
I insist that I am not against innovation, and the state and effects story (and concurrency) are the one things that can have the biggest impact on our user interface implementations. Which means that doing it wrong conversely magnifies the ill. Glad to see that there is a RFC to get comments and hope you guys give it more thinking.

@JCB-K with a special mounted parameter, how would you do something like this?
useEffect(() => {
  const timeoutId = setTimeout(() => console.log('hi'), 1000);
  return () => clearTimeout(timeoutId);
});

Also, I feel like this is a fairly common pattern for subscriptions. For example, a redux store's subscribe function returns an unsubscribe function.

If you think that the requirement of useState() calls to be in the same order between renders is some sort of "foot gun", you should try to write a function that shuffles its variables declaration every time you call the function. It takes some effort to actually do it, especially since we all use block scoped variables these days (let, const). That is not what you would intentionally write in a generic component of your system.

I completely agree with this. Some people seem to be concerned about the ordering of hooks calls, but honestly, I haven't seen a single example in which case it might be a problem. Why would you need to eg. introduce conditional state, what would be a purpose of that? Or if you need a loop, you can as well have an array in a single state hook. I would love to see some actual issues instead of just rumbling that dependency on order is bad.

@sebmarkbage, is it possible to do some sort of "get derived state from props" using useState()? Here is an example I've tried but it didn't work as I expected:
function App() {
  let [start, setStart] = useState(0);

  return (

      <Counter start={start} />
      <button onClick={() => setStart(start + 10)}>Bump</button>

  );
}

function Counter({ start }) {
  let [count, setCount] = useState(start);
  return (

You clicked {count} times

      <button onClick={() => setCount(count + 1)}>Increment</button>

  );
}

I was expecting to have a counter component depending on start value from its parent. Basically, I can do incrementation of Counter's state and I expected the state to be overridden by start prop once the parent sends a new value of it. Current behavior is that Counter's state is not changed when a new start prop arrives. I assume it may be expected since otherwise there can be a case where child component's state is reset to the initial value simply because parent was re-rendered.

@alexeyraspopov
<Counter key={initialStart} start={initialStart} />

Are there any thoughts on what the Devtools/debugging semantics are going to look like for hooks? My main curiosity is multiple useStates would be presented to a developer:
https://codesandbox.io/s/9l6qkmlxmy
https://9l6qkmlxmy.codesandbox.io/

In this example, it looks to only be displaying the first useState hook's data as the state for the Example component. I wonder (and I have no idea if this could be done ergonomically) if each hook's contents could end up named & isolated in the Devtools in such a way that they could be manipulated independently.
(Obviously, all of this is with the caveat that this whole thing is an alpha release and that I think it's super-awesome that the DevTools can display some of that data at all)

I can confirm that the new API can be definitely typed in TypeScript. 😄
For now, this snippet will allow you to use useState and useEffect in a type-safe manner.
const useState: UseState = (React as any).useState
const useEffect: UseEffect = (React as any).useEffect

type UseState = {
  <T>(getInitialState: () => T): [T, StateSetter<T>]
  <T>(initialState: T): [T, StateSetter<T>]
}

type StateSetter<T> = {
  (updater: (oldState: T) => T): void
  (newState: T): void
}

type UseEffect = (
  effect: () => void | (() => void),
  dependencies?: any[]
) => void

Tested with these scenarios:
const [a, setA] = useState(1)
const [b, setB] = useState(() => 1)
const _a: number = a
const _b: number = b
setA(2)
setA(c => c + 1)
setB(2)
setB(c => c + 1)
useEffect(() => {}, [])
useEffect(() => () => {})

@jblock It seems to be rendered in devtools as linked list. You can traverse the next state key to get to the next useState data, but this depends on we knowing which corresponding to which.

A bogus non-rendering component may be used to allow debugging.
const Debug = () => null

function Example() {
  const [count, setCount] = useState(0);
  const [otherCount, setOtherCount] = useState(0);

  return (
    <Fragment>
      <Debug count={count} otherCount={otherCount} />
      ...

Although it works for now, I think it is not so ideal. I would love to hear from React team’s take about DevTools integration.

Even if we don't want to keep the functional components that pure why not pass the hooks object as an additional argument? Like:
(props, { useState }) => { ... }

@mauriciomelo, I think the biggest issue with this approach is inability to define and reuse custom hooks in the way that would align the use of default hooks. Here is an example:
import React, { useState } from 'react';

function useToggle(initialValue) {
  let [toggle, setToggle] = useState(initialValue);
  return [toggle, () => setToggle(!toggle)];
}

function SomeView() {
  let [name, setName] = useState('Liza');
  let [isAdmin, toggleIsAdmin] = useToggle(false);
  // ...
}

Basically, if hooks were coming from the second argument of a component, how would you define useToggle() in the way that it can be reused in different components?

Question: Can you wrap useFoo callsites in conditionals if you can guarantee that all following callsites retain their "callsite index"? Does the following code work?
function Foo(props) {
  props.foo ? useFoo() : useBar()  // must be sure `useFoo` and `useBar` call React hooks the same number of times
  useMixin() // this will be okay :)
}

Sentiment: Thank you for React hooks! Love the API. 🎉
Idea: Thoughts on some kind of useKey function that makes loops/conditionals/nested-functions possible?
function Foo(props) {
  // The return value is whatever the function returns. And `useKey` calls can be nested.
  const [foo, bar] = useKey('ns', () => props.foo ? useFoo() : useBar())
  useMixin() // this will be okay, and anything can happen above us :D
}

@alexeyraspopov
Wouldn't this work?
import React from 'react';

function useToggle(initialValue, useState) {
  let [toggle, setToggle] = useState(initialValue);
  return [toggle, () => setToggle(!toggle)];
}

function SomeView({}, { useState }) {
  let [name, setName] = useState('Liza');
  let [isAdmin, toggleIsAdmin] = useToggle(false, useState);
  // ...
}

@aleclarson

Question: Can you wrap useFoo callsites in conditionals if you can guarantee that all following callsites retain their "callsite index"? Does the following code work?

Not sure what logic are you trying to follow in there, but apparently you cannot do that.

Another idea: Thoughts on useRef returning a writable value?
const foo = useRef(null)
useEffect(() => {
  console.log(foo.current)
  foo.current = true // Triggers a re-render if `foo.current !== true`
})

@FredyC It's an idea, as it says in the comment. Also, I edited the comment with new usage.

function Foo(props) {
  props.foo ? useFoo() : useBar()  // must be sure `useFoo` and `useBar` call React hooks the same number of times
  useMixin() // this will be okay :)
}

At first it seems to be logical to be able to do that, but it also feels weird. Compared to class based components, you wouldn't be even able to do something like that. You would probably have one bulky class that applies logic based on prop value.
Based on the assumption that useFoo and useBar would most likely have very similar (or identical) output, it's imo better to just pass the prop value into that hook and take care of condition in there.

it's imo better to just pass the prop value into that hook and take care of condition in there.

@FredyC I think I agree! It's much cleaner without useKey noise. And there's probably already a library for composing use functions outside the render phase.

because of useState wrap useReducer, how many reducers there will be in a complex app, like an Enterprise Dashboard?
are we sure that performance will be better then Classes and Purecomponent?
i doubt, but i'm expecting real test on real apps

To extend @dtinth's answer, drop this inside your typings folder (configurable via typeRoots in tsconfig.json) to use useState/Effect/Reducer in your current project.
If anyone wants to extend this to cover all hooks and submit to DT feel free, I don't really know how to write their tests...
import "react"

declare module "react" {
  type CleanEffect = () => void
  type DirtyEffect = () => () => void
  export function useEffect(
    effect: CleanEffect | DirtyEffect,
    onlyOnValueChanged?: any[]
  ): void

  type Lazy<T> = () => T
  export function useState<T>(
    initialState: T | Lazy<T>
  ): [T, (newValue: T) => void]

  type Action = { type: A }
  type Dispatch = (action: A) => void
  type Reducer<S, A> = (initialState: S, action: A) => S
  export function useReducer<S, A extends Action<any> = Action<any>>(
    reducer: Reducer<S, A>
  ): [S, Dispatch]
}

Three issues I see with this proposal :

Those functions become procedures. Calling them functions is misleading. How do those procedures compose? Are they even meant to be composed? They are three keys to React which made its success : the view as a pure function of state, React's only concern : the view, and the componentization story. Components do not exactly compose (classes do not compose) but we still have interfaces and polymorphism and patterns.
Those procedures are not just procedures, they are React procedures, i.e. tied to React. Will we still be able to say, switch React for Preact ? The switch was possible because React had a defined interface. Maybe I misunderstand the proposal, but it feels like we loose freedom here. Of course I understand this is more a problem for React's copycats than for React itself.
Because syntactically they are functions, there is no indication of the type information on what effects they perform... We are doing algebraic effects without a type system for it (I am pretty dubious that type script can ever type that). So we have a counter procedure which takes no argument and returns an ever changing React element and we have no idea what else this component did. Obviously documentation would help (but you know how that goes in the real world). The documentation should also specify the order in which effects are performed and of course the effects themselves should also be documented... because all that is part of the semantics of the procedure. At least with classes, we have nominal typing and we can differentiate a class from another one. Classes may have hierarchy too, and that helps knowing what methods they implement. If I extend React,component, I know there is a render method, and I know what that does conceptually because I know the signature of a React component and it is pretty well documented.

Bottom line, I really think React should focus on doing the view thing well, and stay away from other concerns, and having a nice componentization story.

setState provides an optional callback function that will be executed once setState is completed and the component is re-rendered. For useState, will it also provide this callback?

It already does that. I really recommend reading through the whole amazing docs on hooks: https://reactjs.org/docs/hooks-reference.html#functional-updates

setState provides an optional callback function that will be executed once setState is completed and the component is re-rendered. For useState, will it also provide this callback?

I think you just useEffect for that...
function Foo() {
  const [value, setValue] = useState(5)
  useEffect(() => {
    // do whatever you like based on state changes
  }, [value])
}

@zombieJ you can do that with useEffect. instead of thinking "update the state then do this", it'll be "do this when this state value updates"

Basically, if hooks were coming from the second argument of a component, how would you define useToggle() in the way that it can be reused in different components?

By currying:
function useToggle({useState, useEffect}){
  return (initialValue){
    //What to do
  }
}

But because of how indirectly useState (that it is unique per useState call) and useEffect works with components, I don't recommend this approach. As bad as it sound, I hope they refer to somehow like builder pattern for composing react component and reduce indirect assignment approach.

I'm a bit concerned on how it can turn a component less testable and how it makes react less explicit.
This API sounds like that you don't like classes but wanna use functions instead of it.
Why not can it be something more composable like
export default withState({ counter: {
 state: 0,
 setState: (state)=>state+1}})(({
   counter
  }) => ....

Or something that you can understand reading the code more than reading the docs...

@octaviogb That's exactly how recompose functioned :)
As for less testable, I think we're going to have to wait and see what the library support is like for testing. Looking at hooked elements in the React inspector it appears that it isn't complete magic and they still have state, so I don't see any reason why this couldn't be as testable as components are atm with something like Enzyme.

Been using this and reading the docs, and I already hit a dead end with two issues:

I can't useEffect in a way in which I can control to make certain changes only on component updates, and not on mount. Maybe the useEffect callback could receive a boolean flag of whether it's being run on mount or on update?
The setter function returned by useState, does it support the second callback that this.setState supports? The one that's called after the state was really changed.

I can't useEffect in a way in which I can control to make certain changes only on component updates, and not on mount. Maybe the useEffect callback could receive a boolean flag of whether it's being run on mount or on update?

https://reactjs.org/docs/hooks-reference.html#conditionally-firing-an-effect

2. The setter function returned by useState, does it support the second callback that this.setState supports? The one that's called after the state was really changed.

https://github.com/reactjs/rfcs/pull/68#issuecomment-433587560

useCallback seems to be the intended replacement for binding a method in the constructor to avoid passing a new reference into child components on each re-render - and a replacement for withHandlers from recompose. However, the mechanism is completely different, which makes it very easy to create subtle bugs, especially for newer developers.
Example:
const App = () => {
  const [counter, setCounter] = useState(0);
  const increment = useCallback(
    () => {
      setCounter(counter + 1);
    },
    [], // always returns `1` because a new function is needed on update of `counter`
  );
}

The need to do this.handleClick = this.handleClick.bind(this); is not friendly to new developers, but this seems much less friendly, and likely to cause functioning code to break over time. I had to remind myself how closures + memoization work to understand why this was needed.
Maybe with Suspense's deferred rendering, this type of performance optimization just won't be needed often.

@FredyC can you point to where in that section of "conditionally firing an effect" they cover running an effect only on updates, and not on mount? Because I don't see it.
I know also about the answer you gave regarding setState's second callback arg in the comment you linked (I linked to it too). My point is that if I can't use useEffect in a way that my effect only runs on updates, then this second arg to setState was my other option.

I can't useEffect in a way in which I can control to make certain changes only on component updates, and not on mount. Maybe the useEffect callback could receive a boolean flag of whether it's being run on mount or on update?

There are a few ways to do this, I think. One way is to write a custom hook called, say, useIsMounted, to track whether the component is mounted or not. Then, you can use the return value of that hook in your render function, or in other hooks, to determine if it is an update or a mount.

@jamesplease Thanks! Yes, I already considered introducing yet-another-state.
But I feel I shouldn't need to keep this state myself. I'm confident React already knows that information and could give it to me. That's why I raised the issue here in the RFC. To see if what I suspect is indeed possible.

I did some math to compare how using classes vs using hooks affect the size of bundled code. Take a look: https://gist.github.com/alexeyraspopov/2702114ec16794f63ec9c862c995a3dd

@FredyC can you point to where in that section of "conditionally firing an effect" they cover running an effect only on updates, and not on mount? Because I don't see it.
I know also about the answer you gave regarding setState's second callback arg in the comment you linked (I linked to it too). My point is that if I can't use useEffect in a way that my effect only runs on updates, then this second arg to setState was my other option.

That's what second argument of useEffect is for. You can either pass [] (empty array) denoting that there is no dependency and it should fire on mount only or you pass variables which you want to watch (from props) and when those changes it will be fired. And that's also where by passing value from useState you get the same similar behavior like when you were passing the second argument of setState.
This is just mindset issue I believe. I am sure some people will have trouble thinking in different paradigms after learning current ways the hard way. To me, the hooks make much more sense than the lifecycle and all that class-based craziness.

Is there a reason for useMemo not to forward the input values to the computation function?
For example, instead of: useMemo(() => computeExpensiveValue(a, b), [a, b]);
Having something like useMemo(computeExpensiveValue, [a, b]); or useMemo(computeExpensiveValue, a, b, ...);

@Volune Because this way useMemo cannot be covered with types properly.

@TrySound

@Volune Because this way useMemo cannot be covered with types properly.

In fact, with @Volune’s suggestion of useMemo(computeExpensiveValue, a, b, ...), it can be properly typed in TypeScript:
type UseMemo = <T extends any[], R>(
  computation: (...args: T) => R,
  ...dependencies: T
) => R

Hello from the ClojureScript World.
I must say that hooks look very intriguing but I wonder if you'd consider exposing the very low level API for them to the outside world? Something that would expose the createWorkInProgressHook() and the related update queuing for direct use.
There is a problem with inputsAreEqual since ClojureScript datastructures have different equality semantics so CLJS would have to jump through extra hoops to create the extra inputs for the hooks. Also having access to the Low Level API would basically grant use superpowers with macros. Right now in JS "initial" argument to all hooks must be reconstructed on every render and will then be immediately discarded when memoizedState is present (to use useMemo as an example). With a macro the code could just directly emit
const memoHook1 = createWorkInProgressHook();
const memo = inputsAreEqual(memoHook1.inputs, newInputs) ? memoHook1.memoizedState : (function() { ... })();

// generated from
(let [memo (use-memo (fn [] ...)  [cljs-map, cljs-vec, a-string, a-keyword, etc])]
  ...)

So instead of allocating the create fn every time we can optimize that with a conditional. You'd never want to write this in hand by JS but with macros there really isn't any difference. Not sure if that actually improves performance but it would definitely help in situation where constructing the initial argument is costly (eg. (react/useState {:some-nested {:clojure [1 2 :data]}})).
Also I kinda think inputs should be the first argument not the last. Reminds me of setTimeout(some_huge_fn, 1) which would look way better with setTimeout(1, some_huge_fn).

@dtinth Facebook uses flow.

Hooks seem to have a potential to be reused in the context of other view libraries. If the hooks system can be separated from React, the same custom hook can be used with, e.g., Vue:

😆 import {useState} from 'any-hooks';, and in the application import 'any-hooks/register/react'; or import 'any-hooks/register/vue';.

@FredyC, @satya164, thanks for reply. For example, I have a combo select which need focus the input when user click the option in the popup:
onSelectItem = (value) => {
  this.setState({ value }, (() => {
    this.inputRef.current.focus();
  });
};

for hooks:
const [value, setValue] = useState('');

const onSelectItem = (value) => {
  setValue(value);
};

useEffect(() => {
  inputRef.current.focus(); // How to only trigger focus when the `onSelectItem` trigger?
});

@zombieJ Did you try?
useEffect(() => {
  inputRef.current.focus();
}, [value]);

I do get that hooks are great to perform local state things in functional component without writing class-based one, and yes; that's great for humans and compilers!
But.. I think that this conflict with one of the major roles we learned from you related to FP. You talked about presentational and container components, and how it's important to write pure components that depends on the props and wrap it with connect in order to interact with logic (store).
The connect approach made the chance of writing more pure components and wrap them easily with the Redux store (using mapStateToProps and mapDispatchToProps).. but in all the example of the hooks I saw that all the "functional' components started to include some logic inside them which flip their type to act like a containers. So I see with hooks more "containers" components than the past recommended rule of focusing on writing more presentational components.
Can you clarify this point?

@Attrash-Islam The way I see it there is nothing preventing you to have presentation and container components and both to be just functions. Why would you necessarily have to use class for a container component? It's only about semantics in the end. Now you have even more choice as you can hide "logic" inside custom hook and keep most of your components to be presentational. Isn't that sweet? :)

What's the best way to keep an "instance property" like intervals / timeouts? When building a timer with class you would normally do:
class Timer extends Component {
  state = { time: 0 }
  intervalID = null; // how do you store this in hooks model?

  handleStartTimer = () => {
    this.intervalID = setInterval(() => this.setState(s => ({ time: s.time + 1 })), 1000);
  }

  handleStopTimer = () => {
    if (this.intervalID) clearInterval(this.intervalID);
  }

  componentWillUnmount() {
    if (this.intervalID) clearInterval(this.intervalID);
  }

  render() {
    return ( ... )
  }
}

With hooks, this is the closest code I could think of: (using Map)
const Timers = new Map();

export default function Timer() {
  // Generates random ID.
  const [id] = useState(
    Math.random()
      .toString(36)
      .slice(2)
  );
  // Actual timer state.
  const [time, setTime] = useState(0);

  function handleStart() {
    if (!Timers.has(id)) {
      const intervalId = setInterval(() => setTime(t => t + 1), 1000);
      Timers.set(id, intervalId);
    }
  }

  function handleStop() {
    if (Timers.has(id)) {
      clearInterval(Timers.get(id));
    }
  }

  return (...);
}

Should React also expose another API to let us know the ID of current "component instance"?

@raibima You can use use state with a mutable object... e.g.
const [internal] = useState({ intervalID: null })

Then mutate internal.intervalID directly -- that will not cause a re-render.

@raibima If I remember correctly the solution to that was something like.
export default function Timer() {
  const interval = useRef(null);
  const [time, setTime] = useState(0);

  function handleStart() {
    if (!interval.current) {
      interval.current = setInterval(() => setTime(t => t + 1), 1000);
    }
  }

  function handleStop() {
    if (interval.current) {
      clearInterval(interval.current);
      interval.current = null;
    }
  }

  return (...);
}

I'm mainly concerned with the reduced efficiency of PureComponent when recreating functions in render. I guess using hooks would mean that each direct child of the component could not be optimized using PureComponent. Maybe there should be a form of PureComponent that just doesn't care about functions? That diffs all props but functions.
Are there other ideas for solving the PureComponent issue?

@FredyC I don't related to class or function debate. I'm focusing on Presentational vs Containers. The past recommendation was to write more Presentational that depends only on their input (props) so they can be pure and write when needed a wrapping container to pass the things from global state.
With hooks your logic is mixed so you don't have pure things wrapped in logic but rather a components with hooks looks like more containers. So now we write more containers than writing more Presentational

I do get that hooks are great to perform local state things in functional component without writing class-based one, and yes; that's great for humans and compilers!
But.. I think that this conflict with one of the major roles we learned from you related to FP. You talked about presentational and container components, and how it's important to write pure components that depends on the props and wrap it with connect in order to interact with logic (store).
The connect approach made the chance of writing more pure components and wrap them easily with the Redux store (using mapStateToProps and mapDispatchToProps).. but in all the example of the hooks I saw that all the "functional' components started to include some logic inside them which flip their type to act like a containers. So I see with hooks more "containers" components than the past recommended rule of focusing on writing more presentational components.
Can you clarify this point?
Thanks a lot for your innovation. We learn always from the React team everyday about good patterns and functional things

@sebmarkbage @gaearon @acdlite @sophiebits Can you elaborate on this pls?

@zth useCallback or useReducer

https://reactjs.org/docs/hooks-reference.html#usecallback
https://reactjs.org/docs/hooks-faq.html#how-to-avoid-passing-callbacks-down

With hooks your logic is mixed so you don't have pure things wrapped in logic but rather a components with hooks looks like more containers. So now we write more containers than writing more Presentational

Once again, using container vs presentational component is purely about a semantics and up to you how you want to build your code. You can still have presentational components that will receive data from props OR you can use a custom hook inside such component which in my opinion is not really a difference from using HOC or render prop component.

It would be better if you put the hooks in a separate package because usually, we will create own hooks in separate files where is no React.createElement, but react import already exists
The  import from react/hook looks better

why not use a stream for this
  count = stream(0)

  count() // get
  count(count() + 1) // set

I enjoy a lot this new hook feature. First i want to thanks you all for your great work team.
After reading this in the FAQ about the "previous state" management :
// FAQ code from https://reactjs.org/docs/hooks-faq.html#how-to-get-the-previous-props-or-state
function Counter() {
  const [count, setCount] = useState(0);
  const prevCount = usePrevious(count);
  return
Now: {count}, before: {prevCount}
;
}

function usePrevious(value) {
  const ref = useRef();
  useEffect(() => {
    ref.current = value;
  });
  return ref.current;
}

Here is a quick proposal about it.
Why not consider to directly provide this "previous value" in a smart way :
// proposal 1 : all the time, may be perf issues ?
function Counter() {
  const [count, setCount, prevCount] = useState(0);
  return
Now: {count}, before: {prevCount}
;
}

Or only on demands :
// proposal 2 : with options
function Counter() {
  const [count, setCount, prevCount] = useState(0, {widthPrevious: true});
  return
Now: {count}, before: {prevCount}
;
}

Or :
// proposal 3 : with dedicated hook
function Counter() {
  const [count, setCount, prevCount] = useWatchedState(0);
  return
Now: {count}, before: {prevCount}
;
}

Or :
// proposal 4 : with smart function chaining <3
function Counter() {
  const [count, setCount, prevCount] = useState(0).withPrevious();
  return
Now: {count}, before: {prevCount}
;
}

Whatever the API and names can be. It may be very usefull and give an easy way to pass from Classes to Hooks.

@raibima your code will be much simpler with hooks:
const Timers = new Map();

export default function Timer() {
  const [time, setTime] = useState(0);

  useEffect(() => {
    const intervalId = setInterval(() => setTime(t => t + 1), 1000);

    return () =>  clearInterval(intervalId);
  },
  [
    // pass the props which trigger creating interval when they change
    // or empty if you only create timer on mount
  ]);

  return (...);
}

@DavidBabel I believe the React should not have all hooks and its variants people can come up with. It's very important that custom hooks like you have presented are easy to create so it's only a matter of (short) time before libraries with common hooks start popping out. There is also interesting service Bit I found recently that would be almost ideal for publishing these small pieces of code.

@FredyC From the FAQ we can read this lines which takes my interest :

It’s possible that in the future React will provide a usePrevious Hook out of the box since it’s a relatively common use case.

And it's actually a VERY common feature. Leave it to a third party, for a so small and usefull feature, is not necessary. And it prevent an additional line in package.json, one import etc ... i guess it's easy to think about a smart short approach for this.

@FredyC

That's what second argument of useEffect is for. You can either pass [] (empty array) denoting that there is no dependency and it should fire on mount only or you pass variables which you want to watch (from props) and when those changes it will be fired. And that's also where by passing value from useState you get the same similar behavior like when you were passing the second argument of setState.

Once again, what I am trying to do is to have the effect not be run on the initial mount. Only on subsequent updates. What the docs describe, and you reiterate above, covers how to run the effect on mount only, or on mount plus on updates. I'm talking about running it on updates, but not on mount.
Can you still say this is possible, and in so, how? The docs do not seem to cover it.

What about async stuff like fetching something on click or collecting and sending enormous forms?

@Attrash-Islam
Components with hooks are still pure in the sense their output depends on their input. useEffect() describes an effect but doesn't execute it, similar to algebraic data types, for example.
The only downside is that the use of hooks cannot be determined from the return type of the component.  This is a win for encapsulation (the caller never needs to worry about hooks) but a loss for functional purity (you can't determine if something has any side effects or not). You couldn't do that in non-hacky ways at runtime with class components though unless you manually inspected the output of React.createElement and even then it wasn't a sure thing.
if (React.createElement(Foo).type instanceof React.Component) {
 // this component might have side effects!
 // it might also just use lifecycle methods, though...
 ..
}

I think in terms of pragmatism this approach is way better. There are less ways to screw up lifecycles and state (aside from avoiding infinite render loops), it's much easier (for me personally) to read as well and is more declarative which suits React well.

@gnapse you could do something like this:
export default function App() {
  const isMountedRef = useRef();

  useEffect(() => {
    if (isMountedRef.current) {
      // component was mounted earlier
      // run your effect here
    } else {
      isMountedRef.current = true;
    }
  });

  return (...);
}

@Miziak
export default function App(props) {
  const [user, setUser] = useState(null);

  useEffect(async () => {
    const user = await fetchUser(props.id);

    setUser(user);
  }, [props.id]);

  return (...);
}

@gnapse Why do you need to do that? Having anything running on update only instead of depending on the value of props seems like an anti-pattern. Could you explain your use case?

@satya164 I mean something else. Your example perform side effect "onMount" not onClick what if I want collect form data and send it to backend next let's say I want to display popup. Is it usecase for hooks? Because it's very common "pattern" in our apps.

@Miziak hmm, my code does the submit on click.

Is it usecase for hooks?

I don't think there's anything special here for hooks. You would do it the same way you did without hooks.

Just throwing around an idea, don't know if it was already discussed. Wouldn't it make it easier conceptually to understand, safe by default and easier to optimize with a different type of functional component that returns a render function?
function Counter(initProps) {
  const [count, setCount] = useState(0);
  return (props) => (<button onClick={incrementCount}>{count}</button>);
}

Cons:

need a way to flag the component for React to know it's not a standard function component (decorator?)
a bit more verbose

Pros:

no magic / easy to understand conceptually
safe by default, the init code is only called once so no weird rules
framework can detect hooks declaration in a render and throw a helpful message
optimized by default, callbacks and other hooks functions are only declared once, reference equality is maintained, pure components children are happy
framework implementation is probably easier

Another idea for position-independent useState, with API similar to createContext:
import React, {createState} from 'react'

// creates a unique identifier, using Symbol or integer
// `const count = getCount()` and `setCount` inside component work essentially just as `const [count, setCount] = useState(0)`, but use the created identifier instead of position to determine which state to get
const [getCount, setCount] = createState(0)

function Example {
  const count = getCount()
  return (

You clicked {count} times

      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>

  )
}

@FredyC
issue created 👍

@FredyC: I find a bit fascinated that since the hooks popped out, people are starting to think about their current problems and how to use hooks to solve them. Does that mean all current approaches were so bad that they need new ways or is it just "I have to use shiny new thing"?

I think it's important to think about how to solve the current problems using hooks, not because they were very bad, but because if hooks are supposed bring feature parity with class components for function components, then they should address the use cases. Otherwise they aren't a good alternative, and we'll still have to refactor function components to class components if we have a use case which function components didn't solve, like before. This was my biggest gripe with function components and made me always avoid them.
I think hooks are even better than what class components have. They solve many issues better than class components have. They aren't the ultimate solution, but they just feel much better.

@Hypnosphi: Another idea for position-independent useState, with API similar to createContext:

With your example, there's no way for React to know which components to re-render when you call setCount. Also for hooks which depend on props, it's not feasible.

there's no way for React to know which components to re-render when you call setCount

I see. How about something like that then?
import React, {createUseState} from 'react'

const useCount = createUseState()

function Example {
  const [count, setCount] = useCount(0)
  return (

You clicked {count} times

      <button onClick={() => setCount(count + 1)}>
        Click me
      </button>

  )
}

@Hypnosphi Can you instead provide an example where do you think it's actually a problem to be dependent on the order of calls? Many people are trying to find the issue there, but I haven't seen any real use case where it would matter...

trying to find the issue

It doesn't require trying too hard to find one. It's a kind of counter-intuitive magic which wasn't present in React before. As for practical examples, the patterns that Rule 1 forbids are the most obvious ones.
See also https://github.com/reactjs/rfcs/pull/68#issuecomment-433149789

I see. How about something like that then?

That would work, though I think it'll only work for useState. For other hooks like useEffect, it might not work when you run them inside conditionals etc. Things like useContext will still not work when you call them inside a callback.

it might not work when you run them [useEffect] inside conditionals etc.

when an effect with a particular ID is not used anymore because of a conditional, it should be cleaned up

Things like useContext will still not work when you call them inside a callback.

Of course you still shouldn't use hooks outside of component function. That's the Rule 1 that confuses me, not Rule 2 at all

@Hypnosphi

It doesn't require trying too hard to find one. It's a kind of counter-intuitive magic which wasn't present in React before. As for practical examples, the patterns that Rule 1 forbids are the most obvious ones.

I can agree on that it's unusual and requires mind shift, but that doesn't mean it's wrong. I don't get it why it should be causing issue eg. later in production. Assuming you have a functional component that does not change dynamically, why it would behave differently later on? It's completely deterministic behavior imo.

Plus the point on debugging by @benjamnde https://github.com/reactjs/rfcs/pull/68#issuecomment-433148371

That's the Rule 1 that confuses me, not Rule 2 at all

Callbacks are nested functions, so it's still rule 1 :)
I think it's impossible completely eliminate rule 1.
I think the debugging could be solved by better debugging tools in React Devtools. I'd wait since hooks is still an RFC.

@FredyC I didn't post a code example earlier and don't think it's necessary to prove that it's something you might wish to do, but I do think that Hooks should be amended in order that beginner's that make the error of conditional or misordered calls can get an invariant error telling them not to do this. It can't be assumed that there is a linter or that somebody has read the docs. Eventually somebody is going to accidentally do this, and when they do it would be preferable for them to not get errors from within React or silent failures.

Callbacks are nested functions

Okay, nested functions are mentioned in rule 1 but they are also regular JavaScript functions so if rule 1 is eliminated they are still forbidden by rule 2.

JavaScript functions so if rule 1 is eliminated they are still forbidden by rule 2

Ok, but the point is that rule 1 is still not eliminated

The implicit "magic" also frightens me off very much. But then I noticed that we can live with it for a long time: If it is executed via JSX, we are used to it that the library (e.g. react) recognizes correctly when it has to render something new, when for example componentDidUpdate is executed or that a component is not created again and again.
At first it seems very daunting, but is it possible to create the hooks using jsx as well, e.g:
function Counter(props) {
  const [count, setCount] = <UseState initialState={0} />;

  return (
    <React.Fragment>
      <UseEffect>
        {() => {
          document.title = `You clicked ${count} times`;
        }}
      </UseEffect>
      ...
    </React.Fragment>
  );
}

Many people have already shown that hooks wouldn't be so deterrent if they were just introduced as new syntax, so why not really use a different syntax?

The one thing that puzzles me is: why do you want this to be part of the core? I wrote a POC port of the proposed API as a library for Mithril, and it seems to work fine.
The main difference from this standpoint between Mithril and React is the possibility to redraw subtrees using setState, but I suppose that the useState hook could be tied to setState under the hood...

is that rule 1 is still not eliminated

If it's limited to callbacks, it'll be understandable for me personally, as callbacks are not executed inside component function

but is it possible to create the hooks using jsx as well, e.g:

it still wouldn't solve the main constraint. we'll still need to follow the rules like no conditionals, no nested functions etc., have to call before top level etc. JSX elements returning something different than React elements are also confusing.

If it's limited to callbacks, it'll be understandable for me personally, as callbacks are not executed inside component function

They aren't executed inside component function only if they are asynchronous. but the most common callbacks are things like Array.map which are synchronous and called inside the function, so it's still confusing. though if we have this rule anyway, I think having the other rules is okay too.
I'm also not sure how composition will work with the suggested approach. Right now you could just copy the code to a different function to refactor.

Another, probably more convenient option for createUseEffects API:
import { createUseState, createUseEffect } from 'react';

const useIsOnline = createUseState()
const useFriendStatusEffect = createUseEffect((friendID, handleStatusChange) => {
  ChatAPI.subscribeToFriendStatus(friendID, handleStatusChange);
  return () => {
    ChatAPI.unsubscribeFromFriendStatus(friendID, handleStatusChange);
  };
});

function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useIsOnline(null);

  function handleStatusChange(status) {
    setIsOnline(status.isOnline);
  }

  useFriendStatusEffect(friendID, handleStatusChange);

  return isOnline;
}

@Hypnosphi I am confused what does that solve really. Didn't you just move order dependency outside the function scope? How is that any better? Perhaps I am missing some internals here, but wouldn't this be causing the same issue?
import { createUseState } from 'react';

const useIsOnline = createUseState()
const useIsAlive = createUseState()

function useFriendStatus(friendID) {
  const [isOnline, setIsOnline] = useIsOnline(null);
  if (isOnline) {
    const [isAlive, setIsOnline] = useIsOnline(null);
    return 'Online & Alive'
  }
  return 'Offline'
}

@FredyC you use useIsOnline instead of useIsAlive, is it intentional?

@FredyC you use useIsOnline instead of useIsAlive, is it intentional?

Sorry, that way a typo, it's fixed now

@gnapse thanks! in that  case i would probably use a flag that indicates the input has been 'touched' - similar to how react works. not the most ideal situation but i encountered this issue the other day in existing react with stateless components and that's the solution i came up with.
alternatively, you could still use class components if you need that level of control over the lifecycles. SFCs will never be the place for that.

@FredyC OK, why do you think your example won't work then?

Components with hooks are still pure in the sense their output depends on their input. useEffect() describes an effect but doesn't execute it, similar to algebraic data types, for example.

This is the kind of confusion brought about by this that would be better avoided. We have a counter 'function', which takes no arguments, and thus, being pure can only return a constant (because it is always called with the same input which is nothing). What it actually returns is React element with a different count value. I don't know the shape of React element (maybe they are functions) but I would not think it returns the same React element at each call. And even then, if useEffect is not pure, then the function cannot be pure. And you can tell useEffect is not pure as you can call several times with same inputs and it famously returns different values as showcased in the examples in the doc. If we stay in a world with pure/impure instead of pure/pure in the sense that/almost pure/less pure than/rather impure/totally impure, we can better reason about the programs we write.
Here our input-less functions have state, and that state is the state of the React interpreter, so we cannot reason about our functions without reasoning about React and React state (or trust magic). We are writing React script just as we are writing Angular script when we dabble in Angular2.

The only downside is that the use of hooks cannot be determined from the return type of React.createElement() or from the definition of the component utilising the hook. This is a win for encapsulation (the caller never needs to worry about hooks) but a loss for functional purity (you can't determine if something has any side effects or not).

The caller has to worry about the semantics what it is calling... and those semantics are not apparent. The only to get them is having somebody writing them for you. And then you have to understand them. And then you have to imagine how it may interact in a concurrent context and trust yourself that you got everything right.

I think in terms of pragmatism this approach is way better. There are less ways to screw up lifecycles and state (aside from avoiding infinite render loops), it's much easier (for me personally) to read as well and is more declarative which suits React well.

Procedures are nothing new to programming. This is how software was written before object-oriented paradigms took the world, and there have been good software written in those days just like in ours. Of course procedures/impure functions are more powerful than pure functions. This is the  power vs. properties tension. By restricting what you can express you get properties in exchange which allow you to better reason about your program. Conversely by dropping your ability to reason about your procedure and trusting it to React you can express more stuff more concisely. That is a fact and that is why there is a hook proposal in the first place. What people need to know before they run into the new shiny thing, is what are the drawbacks. The success of libraries modifying Object prototype almost killed javascript a decade ago ; but at that time it looked like a great idea and wonderful syntax and so pragmatical. Some of these drawbacks can be anticipated without writing a single line of code. Others will only be discovered through trials and errors thus the current experimentation.
That's how the React's API evolved. Some stuff got deprecated in exchange of others after people used it for a while. I am speciallly worried here though, because once you have people jumping on that wagon, you can say all what you want that you are not removing classes from React, you will have anyways to master the hook thing because you will have to include third-party code who do. And I say master because let's not fool ourselves, bugs will not disappear and we will have to understand  everything going under the hood, even if now it is just cool we skip 5 lines of code. Once you open that door, it will be hard to close. We people have a tendency to go for the easy before going for the sound. So let's think and experimient much more before opening the door.

@FredyC OK, why do you think your example won't work then?

I guess nevermind, it is too contrived. The same thing would work with current implementation as well. I would stick to what @danpantry said and instead of looking for examples that are trying to break things, let's focus on real code that would actually cause problems. Beginners mistakes aside, for now, everyone will do them.

@brucou I agree with most things you said, it was a mistake to describe it as pure since, yes, it depends on the react state. :)

The caller has to worry about the semantics what it is calling... and those semantics are not apparent. The only to get them is having somebody writing them for you. And then you have to understand them. And then you have to imagine how it may interact in a concurrent context and trust yourself that you got everything right.

Do I have to worry about that? If I'm consuming a component that uses hooks vs one that is a classical stateful component and I am using React, I don't have to care what I am calling as a consumer of that component. Unless I am misunderstanding your question?

And then you have to imagine how it may interact in a concurrent context and trust yourself that you got everything right.

I would agree here if React (or JavaScript) was concurrent, but it's not. Even if JavaScript was concurrent, React is explicitly designed to execute in a specific order. So, in theory, yeah, this could be a problem, but in practice it's not.

@danpantry

@gnapse In this case yeah I think you want to use class components if you need that level of control over lifecycles. Either that or you need to have another flag that indicates if the isEditing field has been changed at least once. I don't see how you get around this using functional components.

If that's the definitive answer and is confirmed by the React team, that would be unfortunate. It would mean that the new feature cannot fully replace class components in 100% of the cases (well not exactly because of the solution with the additional state, but that solution sucks IMO, especially when it's pretty safe to assume that React knows if its running an effect on mount or not, and could easily provide that info to the effect callback).
useEffect(({ isOnMount }) => {
  // isOnMount is boolean, true when running on component mount, or false otherwise
});

Another controversy which is almost become an iconic symbol embedded in React's spirit. Ok, I like the concept and I'm fine with the API, I know here have many people came up with some degree of concerns and arguing some problems (like the name, does anyone feel useEffect should call useAfterRender instead?).  But one step back, I really want to echo with @pygy , does hook have to be in the core, really???
So far, the use of hooks is more like importing something out of the library, and I think it should be extracted out of the React as a standalone library, since the core team also says:

Hooks are opt-in.

The biggest issue for me is my team member will get exciting to use this new toy, so do I.  But, when we build a large application, this "new feature" is looking like inevitably to be turned on automatically after it shipped with React 16.7.  That is a big red flag for me.  It requires many internal educations and communications, and even set up a meeting to discuss if we now can stop writing class and just using hook or to define our adaption strategy.
We still want to upgrade with our package since it may fix some bugs for us.  But, shipping together with a bunch of something we are not so sure about it today... Uhh... I feel something wrong here. Sounds similar? It recalls me our old friend mixin, now is a deprecated feature in React which used to a hero then became an anti-pattern.
I'm worrying as if that will be the same as using React class one day. But the case we have today is even worse.  Because the team also says:

There are no plan for removing class component from React.

This means both class and function component + hooks will co-existing for a foreseeable future. Yeah... A new apex in React's learning curve for a newbie to learn it at the ground.
I get hyper first and then worry more about my poor team.  I love it, it is so functional and useful, but I think hooks need to be out-out by default for a reasonable long time.  I mean, the API of hooks should shipped separately, though their implementations can come together with the core.  Once hook-API is mature enough so that we can say goodbye with class, then we can swap their position.

does hook have to be in the core NOW

Why not? They rely on React internals.

@gnapse

If that's the definitive answer and is confirmed by the React team, that would be unfortunate. It would mean that the new feature cannot fully replace class components in 100% of the cases (well not exactly because of the solution with the additional state, but that solution sucks IMO, especially when it's pretty safe to assume that React knows if its running an effect on mount or not, and could easily provide that info to the effect callback).