Git Product home page Git Product logo

Comments (16)

Lodin avatar Lodin commented on July 26, 2024 3

I've been thinking a lot about implementing React-like context to Web Components and finally found an answer: why it should be React-like? Especially when React team itself decided to kill old-style context and create a new one.

In my opinion, React relies on components too much. They even replaced class inheritance with HOCs, trying to make classes looking like a function. It still doesn't work, because component have their own lifecycle, and it breaks the very idea of component = function (I think React is great project changed everything in web development though).

Web Components are different. While React has its own compiler starting with React.render(), Web Components don't have any external system to inject context as React does. But they don't have to do it, because we have a great platform-close tool to achieve any necessary context we need.

Just create a factory that consumes your store and produces connect function, and it will work without any special context:

// createConnect.js
export const createConnector = store => (mapStateToProps, mapDispatchToProps) => baseElement => {
       return class extends baseElement {
           connectedCallback() {
                this.__storeUnsubscribe = store.subscribe(() => this._stateChanged(store.getState()));
                ....
           }

           disconnectedCallback() {
              if (this.__storeUnsubscribe) {
                  this.__storeUnsubscribe();
              }
               ...
           }
       }
   }
// connect.js
export default const connect = createConnect(createStore());

That's it. You don't need extra code to support complex system of context as it was in React.

Also I think it is very similar approach the new React context has. They use a function to create Provider and Consumer components that are exchanging value property between each other. But we don't even need components to do it, everything is built-in.

from lit-element.

blikblum avatar blikblum commented on July 26, 2024 3

I created wc-context library that supports lit-element and skatejs as well vanilla web components

The API is still in flux

from lit-element.

Westbrook avatar Westbrook commented on July 26, 2024 2

This talk was posted to the Slack channel, and it might be of interest to this conversation as it came up in the context of Context Properties there: https://youtu.be/6o5zaKHedTE

from lit-element.

askbeka avatar askbeka commented on July 26, 2024 1

@Westbrook , Thanks, that is an amazing approach, Never occurred to me.

from lit-element.

sorvell avatar sorvell commented on July 26, 2024 1

This outside the scope of LitElement since it is focused on creating custom elements that work with normal DOM API's. We might reconsider adding an API like this in the future if there's enough interest and a concrete proposal.

We recommend looking at PWA Starter Kit for docs, examples, and best practices around using LitElement when making PWAs and other web apps. It uses Redux for state management.

from lit-element.

askbeka avatar askbeka commented on July 26, 2024 1

@Lodin More news on this topic,
With new CSS display type display: contents.
You should not be afraid of extra DOM, since it does not affect layout.
It is slready supported by 83% of browsers

from lit-element.

askbeka avatar askbeka commented on July 26, 2024

@Lodin . Thank you for your response. But, one of the problems this issue addresses is testability and SSR. Problem with having static connect or store exported from the module makes it singleton, and harder to mock the store while testing and when doing SSR, especially when your app is a part of a larger app. This is issue also mentioned here.

I agree that having component in dom that does not have any visual footprint but just passes context can be confusing. probably this should not be a part of LitElement, more of a pwa-helpers. Iยดll do a PR with and idea I have and link it here soon.

from lit-element.

askbeka avatar askbeka commented on July 26, 2024

I have created a small lib called it wc-context, no packaging yet, its coming soon. In meantime want to get some feedback. There is a Redux exmaple in demo folder.

from lit-element.

Lodin avatar Lodin commented on July 26, 2024

@askbeka I still think the functions are better for it. I've got an idea to make them static and mimic new React.Context API completely.

const createContext = (default) => {
  let ctx = default;

  const provide = (newCtx) => {
    ctx = newCtx;
  }

  const consume = () => {
    if (!ctx) {
      throw new Error('Context is not defined');
    }

    // do whatever you want from consumer
  }

  return {consume, provide};
}

export {
  consume,
  provide,
} = createContext();

What do you think about this approach?

from lit-element.

askbeka avatar askbeka commented on July 26, 2024

@Lodin , This approach is not much different from just using store in component, I am not saying that it is bad, it may be all you need if you have one team working on whole app and it is not big. But in other cases this apprach does not scale very well.

Imagine that you have an app that is being developed by multiple teams some of them can be offshore and they have their own source control. You can store context as a global object in page and make them use that, but then you have a problem if you need multiple stores in your app, and components should be used with different stores.

Good thing that we have DOM and custom element and events to solve that. I am experimenting with it, for now I am not really happy with API, but I will try to release alpha version soon to get more feedback.
I don't have much time unfortunately:(

from lit-element.

Lodin avatar Lodin commented on July 26, 2024

@askbeka Oh I see it now. Thanks, talking with you was really useful. Waiting for your context lib!

from lit-element.

satouriko avatar satouriko commented on July 26, 2024

Thanks for @Westbrook mentioning Justin Fagnani's presentation, @askbeka's demo code and @blikblum's library.

from lit-element.

askbeka avatar askbeka commented on July 26, 2024

@rikakomoe you are welcome. Thanks for reminding. Almost forgot about this issue.
I couldn't find time to update on my final solution.

But, since then I have contributed context implementation for haunted.
Which implements reacts's hooks pattern with webcomponents.

There is also recent ongoing attempt to make react-redux work you can track here

from lit-element.

satouriko avatar satouriko commented on July 26, 2024

@askbeka The official guide requires a constant existing store before defining the element. The issue is, besides it is not tidy enough though, I am not building a website but a component, if the user creates more than one instance, all of them need their independent state. So I was looking for a declarative method to inject this store into children components, for convenience, without passing down the store over and over. React provides this dependency injection feature as its context while lit-element doesn't yet.

I'm interested about your final solution, if there were any updates/improvements against the solution I've seen so far.

from lit-element.

Lodin avatar Lodin commented on July 26, 2024

@rikakomoe, you can also try my context approach that implemented in the @corpuscule/context library. It allows avoiding unnecessary HTML elements whose only purpose is to serve as a provider. With this library, you can make your root component a theme provider, a redux provider, a router provider, etc. at the same time without creating expensive HTML elements and increase nesting. It works with any implementation of web components.

The library is based on decorators, so you will need Babel to transpile your components while the decorator proposal is in development. Corpuscule project provides solution for it as well.

BTW, the redux bindings (based on the context library) are also there: @corpuscule/redux. It also works with any web component library as well as vanilla web components.

from lit-element.

satouriko avatar satouriko commented on July 26, 2024

@Lodin Thanks!

from lit-element.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.