Context
Added in Roact 1.3.0
Roact supports a feature called context which enables passing values down the tree without having to pass them through props. Roact's Context API is based onReact's Context API.
Context is commonly used to implement features like dependency injection, dynamic theming, and scoped state storage.
Basic Usage¶
localThemeContext=Roact.createContext(defaultValue)
Context objects contain two components,Consumer
andProvider
.
TheConsumer
component accepts arender
function as its only prop, which is used to render its children. It's passed one argument, which is the context value from the nearest matchingProvider
ancestor.
If there is noProvider
ancestor, thendefaultValue
will be passed instead.
localfunctionThemedButton(props)returnRoact.createElement(ThemeContext.Consumer,{render=function(theme)returnRoact.createElement("TextButton",{Size=UDim2.new(0,100,0,100),Text="Click Me!",TextColor3=theme.foreground,BackgroundColor3=theme.background,})end})end
TheProvider
component accepts avalue
prop as well as children. Any of its descendants will have access to the value provided to it by using theConsumer
component like above.
Whenever theProvider
receives a newvalue
prop in an update, any attachedConsumer
components will re-render with the new value. This value could be externally controlled, or could be controlled by state in a component wrappingProvider
:
localThemeController=Roact.Component:extend("ThemeController")functionThemeController:init()self:setState({theme={foreground=Color3.new(1,1,1),background=Color3.new(0,0,0),}})endfunctionThemeController:render()returnRoact.createElement(ThemeContext.Provider,{value=self.state.theme,},self.props[Roact.Children])end
Danger
Legacy Context is a deprecated feature that will be removed in a future release of Roact.
Roact also has a deprecated version of context that pre-dates the stable context API.
Legacy context valuesdo not update dynamically on their own. It is up to the context user to create their own mechanism for updates, probably using a wrapper component andsetState
.
To use it, add new entries toself._context
inComponent:init()
to create a provider:
localProvider=Roact.Component:extend("FooProvider")-- Using a unique non-string key is recommended to avoid collisions.localFooKey={}functionProvider:init()self._context[FooKey]={value=5,}end
...and read from that same value inComponent:init()
in your consumer component:
localConsumer=Roact.Component:extend("FooConsumer")functionConsumer:init()self.foo=self._context[FooKey]endfunctionConsumer:render()returnRoact.createElement("TextLabel",{Text="Foo: "..self.foo.value,})end