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

Missing createContext #475

Open
Pyrolistical opened this Issue Jun 8, 2018 · 8 comments

Comments

Projects
None yet
4 participants
@Pyrolistical

Pyrolistical commented Jun 8, 2018

React libraries that use the new Context API will have import {createContext} from 'react', and that
doesn't work with preact-compat

Should we just re-export https://github.com/valotas/preact-context while we wait for createContext to be added to preact developit/preact#963?

@Pyrolistical Pyrolistical changed the title from Forward createContext to preact-context to Missing createContext Jun 8, 2018

@kontrollanten

This comment has been minimized.

kontrollanten commented Jun 12, 2018

I'm missing createContext too. @Pyrolistical, what do you mean with "re-export"? I'm looking for a workaround until we've something merged in preact or preact-compat.

@mindplay-dk

This comment has been minimized.

mindplay-dk commented Jun 29, 2018

I didn't know preact-context existed!

The fact that this exists really should be documented somewhere in plain sight.

I was beginning to worry that Preact and React were about to diverge too substantially with the introduction of the new context API in React - and also have been looking for a simple solution for application-wide shared state. This looks great!

@developit

This comment has been minimized.

Owner

developit commented Jul 11, 2018

There's some funky bitmask stuff in preact-context that I'm not super sure we need in preact-compat (it doesn't seem to be part of the officially supported React API). Perhaps we could just add something like this?

function createContext(initialValue) {
  const key = `$ctx-${++counter}`;
  class Provider {
    getChildContext() {
      let ctx = this.ctx || (this.ctx = {});
      if (ctx[key]!==this.props.value) {
        for (let i=0; i<subs.length; i++) subs[i].setState(null);
      }
      ctx[key] = this.props.value;
      return ctx;
    }
    render(props) {
      return props.children[0];
    }
  }
  class Consumer extends Component {
    componentDidMount() {
      consumers.push(this);
    }
    componentWillUnmount() {
      consumer.splice(consumers.indexOf(this), 1);
    }
    render(props, state, context) {
      return this.props.children[0](key in context ? context[key] : initialValue);
    }
  }
  return { Provider, Consumer };
}
@kontrollanten

This comment has been minimized.

kontrollanten commented Jul 12, 2018

I've been thinking a bit about this while I've been working on different projects using both React and preact and I'm not sure that I really want this feature into preact anymore.

What I really fell for with preact/React is the inspiration of functional programming and it's "simplicity", in the meaning that without side effects it's really easy to isolate, debug and understand the web clients. Compared to for instance Angular it's, in my opinion, a huge difference in the complexity. My picture is that React now is moving away from this approach and starts to implement side effects in the framework (context), and what I've heard there's more new features to come.

Of course side effects can make web apps easier to build, and also remove complexity. But I think that with the tools to create side effects developers will tend to use those as shortcuts in cases where pure functional programming can solve the same issue. The price for the developers (and the projects) is technical debt.

With the background of this I can really see a purpose with preact not following this trend. I guess the purpose of creating a preact API similar to React was easy migration between those frameworks, but now preact is pretty big and maybe this can be a start for a diverge between those two frameworks where it's not longer obvious that preact should try to follow Reacts pattern.

What do you think?

@mindplay-dk

This comment has been minimized.

mindplay-dk commented Jul 12, 2018

@kontrollanten side-effects is not the only use for this - I'm using it simply as a means of sharing state between related components, e.g. a <TabList> with <Tab> panels, where the panels can share the selected tab state, which is provided by the parent tab-list. (even works fine for nested tabs.)

I guess the purpose of creating a preact API similar to React was easy migration between those frameworks, but now preact is pretty big and maybe this can be a start for a diverge between those two frameworks where it's not longer obvious that preact should try to follow Reacts pattern.

Isn't that why we have preact-compat?

@developit most likely we're talking about an addition to that, not an addition to the framework itself?

I think it's very important to have that feature in preact-compat - the whole point of that package existing, is to provide API-compatible React idioms, and I think there's no doubt the new context API is already a popular idiom in React?

@Pyrolistical

This comment has been minimized.

Pyrolistical commented Jul 12, 2018

yeah, the more I look at preact, the more I think preact should just do its own thing.

Even react regrets the move from createClass to es6 classes, so they are not infallible.

I would love to see preact do its own thing and continue with ideas like having props/state as params in render and simplifying children.

I want preact to be different enough that we won't expect compat at all

@kontrollanten

This comment has been minimized.

kontrollanten commented Jul 12, 2018

@kontrollanten side-effects is not the only use for this - I'm using it simply as a means of sharing state between related components, e.g. a with panels, where the panels can share the selected tab state, which is provided by the parent tab-list. (even works fine for nested tabs.)

@mindplay-dk That's true, but I think my reasons applies for those cases also; it's no longer functional and my opinion is that this behaviour will in many cases increase application complexity.

Isn't that why we have preact-compat?

I was mainly thinking about implementing context API into preact, maybe I should've created this discussion on preact project but I guess that a decision like this will affect both preact and preact-compat.

One way could be to keep preact-compat up to date with latest React features and keep preact slimmed. I'd love a clear distinguish between those projects; where preact strives for a petite, functional rendering framework and preact-compat makes preact easier to use for those who needs React's features, being able to import them one by one.

@developit

This comment has been minimized.

Owner

developit commented Aug 6, 2018

I'm partial to the idea of exporting createContext from preact-compat, and also shipping it as a standalone module (or just pointing to preact-context). It's another dependency for Preact core users, but I think most people actually prefer small composable dependencies at this point.

Going forward, I think the main metric we want to use for whether things get bundled into Preact itself is actually whether they can feasibly be implemented as standalone modules. Something like the new Context API is actually designed to be a standalone module, and nice implementations exist. Something like createRef() is a bit less clear-cut, since Preact could support it in ~40 bytes with the same semantics as React. Supporting createRef as an add-on module is smaller, but the value returned by createRef is a function rather than an Object.

As for preact-compat, I'd like to move the React 0.14.x features into a separate module, a "legacy" version, or just remove them entirely. List-based features like the React.DOM.div factories are just wasteful, and we're putting them into bundles knowing most people will never use them. I'd rather save those bytes for new features, or just give folks some bytes back :)

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