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

useContext or similar global shared state system #213

Open
wcastand opened this issue Jan 5, 2021 · 8 comments
Open

useContext or similar global shared state system #213

wcastand opened this issue Jan 5, 2021 · 8 comments

Comments

@wcastand
Copy link

wcastand commented Jan 5, 2021

i've seen a few mention on it in the different Pr/issues but can't find anything about it in the current fre package.
Is it still something that is planned?
A Pr was also talking about a fre/compat for context. Is this a future plan or already there(couldn't find it)?

@yisar
Copy link
Collaborator

yisar commented Jan 5, 2021

Because of the upgrade of new version fre2, this work was not performed, but this is what we will do in the future.

Shared state may be easy with hooks API, for example:

export const createContext = defaultValue => {
  const context = {
    value: defaultValue,
    subs: new Set(),
    Provider: function Provider({ value, children }) {
      useLayout(() => {
        context.subs.forEach(fn => fn(value))
        context.value = value
      })
      return children
    }
  }
  return context
}

export const useContext = (context, selector) => {
  const subs = context.subs
  const [, forceUpdate] = useReducer(c => c + 1, 0)
  const selected = selector ? selector(context.value) : context.value
  const ref = useRef(null)
  useEffect(() => {
    ref.current = selected
  })
  useEffect(() => {
    const fn = nextValue => {
      if (ref.current === selector(nextValue)) return
      forceUpdate()
    }
    subs.add(fn)
    return () => subs.delete(fn)
  }, [subs])
  return selected
}

const Context = createContext({ count1: 0, count2: 1 })

function App(){
  const context = useContext(Context, ctx => ctx.count1) // selector
...
}

After fre2 is finally released, we can add some api and compat packages, it will be soon.

@yisar
Copy link
Collaborator

yisar commented Jan 5, 2021

Keep this issue open until a better implemention land.

@Rados51
Copy link

Rados51 commented May 5, 2021

It would be great if it would be possible to use somethings like Atoms from Recoil.

@yisar
Copy link
Collaborator

yisar commented May 5, 2021

@Rados51 To be honest, this is difficult, because recoil depends on useContext and useMutableSource, and fre does not have these two APIs yet.

@Rados51
Copy link

Rados51 commented May 5, 2021

@yisar Thanks for a quick response. I've just came across your library and it seems like a perfect solution for project I am working with and it doesn't require whole complexity of React. What would be the best way to pass states between child/parent — props? Thank You and wish you best luck.

@yisar
Copy link
Collaborator

yisar commented May 5, 2021

In fact, if props are passed across components, useContext is the most appropriate, because it does not produce tearings.

If you like atom, you can try jotai, but it is also based on context. I will implement context in fre in the future.

@mindplay-dk
Copy link
Contributor

Check this out:

https://github.com/DaemonAlchemist/unstateless

Compared with context, this seems so much more natural in the context of hooks.

I wonder if something like this wouldn't also be simpler, easier to implement, and possibly smaller, than contexts?

If we had e.g. useSharedState and useSharedReducer, that seems like an shoe-in for a framework with pure hooks, and should pretty much cover all the bases?

(I'm not 100% sure about the naming - these functions aren't technically hooks, but functions that create hooks... so maybe names like createSharedState and createSharedReducer is better?)

I suppose contexts might also be worth supporting - if nothing else, then just for compatibility with React... but if it's actually simpler and easier to implement a more natural API than that...

@yisar
Copy link
Collaborator

yisar commented Sep 1, 2021

@mindplay-dk I don't want to use pub-sub in the core code of fre (just like preact).
If I have to, I prefer to set shoudComponentUpdate for all components, and then use pub-sub similar technologies

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

No branches or pull requests

4 participants