Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Suggestion for API Tweak #77

Closed
timkindberg opened this issue Apr 12, 2019 · 1 comment · Fixed by #78
Closed

Suggestion for API Tweak #77

timkindberg opened this issue Apr 12, 2019 · 1 comment · Fixed by #78

Comments

@timkindberg
Copy link
Collaborator

What do you think of this API? It's a very simple change to the library, but personally I find it more elegant.

import React, { useState, useContext } from "react";
import createContainer from "constate";

// 1️⃣ Create a custom hook as usual
const useCounter = () => {
  const [count, setCount] = useState(0);
  const increment = () => setCount(prevCount => prevCount + 1);
  return { count, increment };
}

// 2️⃣ When you need to share your state, simply wrap your hook
//    with the createContainer higher-order hook, like so:
const useCounter = createContainer(() => {
   // ... same logic here
});

function Button() {
  // 3️⃣ Use the same hook like you were before, with the same api. No change.
  const { increment } = useCounter()
  return <button onClick={increment}>+</button>;
}

function Count() {
  // 4️⃣ But now you can use it in other components as well.
  const { count } = useCounter()
  return <span>{count}</span>;
}

function App() {
  // 5️⃣ The caveat, you wrap your components with the Provider that is
  //    attached to the hook
  return (
    <useCounter.Provider>
      <Count />
      <Button />
    </useCounter.Provider>
  );
}

The change in the code is roughly this (the last 3 lines specifically):

export function createContainer(useValue, createMemoInputs) {
  const Context = React.createContext()

  const Provider = props => {
    const value = useValue(props)
    const { children } = props
    const memoizedValue = createMemoInputs ? React.useMemo(() => value, createMemoInputs(value)) : value
    return <Context.Provider value={memoizedValue}>{children}</Context.Provider>
  }

  const hook = () => useContext(Context)
  hook.Provider = Provider
  return hook
}
@diegohaz
Copy link
Owner

I'm open to it. I guess we can do this without breaking changes if we also expose useHook.Context so people could still use it like today.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants