Context

WebComp's Context is a way to manage a shared state across components

Sometimes you need to do more than just sending events between components. In some cases you might want a way to manage shared state between multiple components. You can do it using WebComp's Context.

Using Context

Here's how to use WebComp's Context

1. Import context

import { WebComponent, register } from '@webcomp/core'
import withContext from '@webcomp/context'

2. Wrap your component in withContext before registering

class SideBarComponent extends WebComponent {
  render(props) {
    return (
      <aside>
        <img src="" />
        <span className="username">@</span>
      </aside>
    );
  }
}

// Provide a name for the context
const SideBar = withContext('user-data')(SideBarComponent)

register(SideBar, 'side-bar')

3. Get context from props

Once rendered, context-enabled component will have access to this.props.context which is an array with a value and a function to set that value:

class SideBarComponent extends WebComponent {
  render(props) {
    const [user, setUser] = props.context
    // You can use setUser to change the value of `user` in the context

    return (
      <aside>
        <img src={user.avatarUrl} />
        <span className="username">@{user.username}</span>
      </aside>
    );
  }
}

const SideBar = withContext('user-data')(SideBarComponent)

register(SideBar, 'side-bar')

Initial context value

By default, any context value you use is going to be set to null on the initial render. You can override this behavior in one of the two ways:

Second argument in withContext

const SideBar = withContext('user-data', { username: 'max' })(SideBarComponent)

getInitialContext static method

You can also specify a static method to provide initial data for the context

class SideBarComponent extends WebComponent {
  static getInitialContext() {
    return { username: 'max' }
  }
  
  render(props) {
    const [user, setUser] = props.context
    // You can use setUser to change the value of `user` in the context

    return (
      <aside>
        <img src={user.avatarUrl} />
        <span className="username">@{user.username}</span>
      </aside>
    );
  }
}

You can return a promise in getInitialContext, but keep in mind that it may result in a content flash if you have async operations in getInitialContext that take too long.

Note: Keep in mind, that both withContext initial value and getInitialContext are only used if the context value doesn't exist. If it has been populated before, they will be ignored.

Last updated