How native-recipe works
createStyleRecipe and createSlotStyleRecipe create recipes and slot
recipes of a style kind on @lynstack/recipe, the
engine that selects, caches, and types them. This page covers what React
Native styles add; see the engine’s
How it works for the rest.
Compiled once, a lookup after that
Section titled “Compiled once, a lookup after that”A recipe compiles its config when it is created: it numbers the options of
each variant, so a selection becomes one integer. The first call for a
selection merges its style and caches it under that integer; every later
call with the same variants reads the option of each variant and returns
the cached style. Create each recipe once, at the top level of a module,
so that its cache lasts. The cache grows with the selections the recipe is
called with, up to one entry per combination of declared options. A recipe
whose config sets cache: false builds a new style on every call, which
changes the style prop on every render, so leave the cache on.
The order of styles
Section titled “The order of styles”A style merges, from the least to the most specific:
base.- The style of each variant’s selected option, in the order of
variants. - The style of each matching compound variant, in the order of
compoundVariants.
A later style overrides the properties of an earlier one, as in
StyleSheet.flatten, and a property set to undefined is copied too.
Defaults apply before compound variants match, so a compound variant can
match a default option. A slot recipe merges the style of each slot in the
same order.
Stable styles
Section titled “Stable styles”What makes a style cheap for React Native is its identity. When a
component renders again and its style prop is the same object as
before, React skips comparing it, and a memoized child that receives it
skips rendering. A style built during the render, such as
{ ...base, ...sizes[size] }, or an array of styles, is a new value on
every render, which React compares property by property, and flattens
when it is an array.
A recipe returns the same frozen object for the same variants, so the
style prop keeps its identity as long as the variants do, as a style of
StyleSheet.create declared outside the component does. A slot recipe
returns the same frozen object, holding the same frozen style for each
slot. Freezing keeps a component from changing a style that every other
call with the same variants shares.
One recipe for each theme
Section titled “One recipe for each theme”A recipe of createThemedRecipes
takes a theme and a selection. The first call with a theme object builds
the config for that theme and compiles a recipe from it, which it keeps
for that object; every later call with the same object uses that recipe
and its cache. So:
- The styles of each theme are cached apart, and switching back to a theme returns its cached styles.
- A theme object must keep its identity: a new object, even with the same tokens, compiles a new recipe with an empty cache. Create each theme once, or memoize a theme built at runtime (see Themes and design tokens).
- A theme that is no longer referenced is released with its recipe.
Undeclared options
Section titled “Undeclared options”The types accept only the options the config declares. A value from untyped data can still bypass them: an option that its variant does not declare adds no style, and its style is built on every call instead of being cached. Properties of the selection that are not variants are ignored, and calling a recipe without a selection is the same as calling it with an empty one.