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

Possible to do lazy splitting at time of hook usage? #108

Open
timkindberg opened this issue May 7, 2020 · 4 comments
Open

Possible to do lazy splitting at time of hook usage? #108

timkindberg opened this issue May 7, 2020 · 4 comments

Comments

@timkindberg
Copy link
Collaborator

timkindberg commented May 7, 2020

Hi Diego! Thinking of using this in addition to or instead of zustand. One thing I like about zustand is that you can select from the state when you use the hook, like so:

// If you don't pass anything to the hook it returns everything, and rerenders when anything changes
const foo = useMyStore()

// However, if you pass a selector fn, then it will only "watch" the selected state.
// Good for perf optimizations.
const foo = useMyStore(state => state.foo)

// By default it's a referential equality check, but you can pass different equality fns.
// So you could pass lodash's isEqual to do a deep equal comparison if you needed to.
const someBigObj = useMyStore(state => state.someBigObj, _.isEqual)

Do you think it's possible to accomplish this with constate? Like this?

import React, { useState } from "react";
import createStore from "zustand";

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

// 2️⃣ Wrap your hook
const [Provider, useCounterContext] = constate(useCounter)

function Button() {
  // 3️⃣ Use store instead of custom hook, make use of selector api
  const increment = useCounterContext(s => s.increment);
  return <button onClick={increment}>+</button>;
}

function Count() {
  // 4️⃣ Use store in other components
  const count = useCounterContext(s => s.count);
  return <span>{count}</span>;
}

function App() {
  return (
    <Provider>
      <Count />
      <Button />
    </Provider>
  );
}
@diegohaz
Copy link
Owner

diegohaz commented May 10, 2020

I'm not sure we can do that, especially the No need for a Provider part. Hooks need to run at the component render phase, and with Constate they run on the Provider component.

Because of that, and because we can't bail out from rendering when using React.useContext, there'll be no difference between these two:

const count = useCounterContext(s => s.count);
// would be the same as
const { count } = useCounterContext();

@timkindberg
Copy link
Collaborator Author

Whoops didn’t mean to add the “No need for a Provider” part!

@timkindberg
Copy link
Collaborator Author

Would this help? https://github.com/dai-shi/use-context-selector

@timkindberg
Copy link
Collaborator Author

Looks like useContextSelector is officially proposed.

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

No branches or pull requests

2 participants