Directives
Directives are React components that can be used to pass values (even rendered) to upper context and control your app from within the page—to direct it what to do, hence the name.
This principle ensures the ability to override the value of a directive from within any nested component.
You can use Title
component that uses directive to control the title of your page at any nesting depth.
You can render default Title
component in the root of your route and override it in any nested component.
1. Setting values with directive in the page
To use a directive that will push value to the parent context just render the Directive
component with the name
and content
props.
import * as React from 'react'
import { CommonSlots } from '@contember/layout'
import { Directive, Title } from '../components/Directives'
export default () => (
<>
<Directive name="title" content="Page Title" />
<p>Some content</p>
<div>
<p>Nested content</p>
<Directive name="title" content="Override Page Title" />
</div>
</>
)
2. Creating Directives
To create a directive, you need to use the createDirectiveContext
factory function.
To make the usage of directives easier, you can create a shorthand component. For example, you can create a Title
component that will render the Directive
component with the title
name.
import { createDirectiveContext } from '@contember/layout';
import * as React from 'react';
type DirectivesType = {
'title': string | null | undefined;
}
const directivesDefaultValues: DirectivesType = Object.freeze({
'title': undefined,
})
export const directivesList = Object.keys(directivesDefaultValues) as (keyof DirectivesType)[]
export const [DirectivesProvider, Directive, DirectivesConsumer, useDirectives] = createDirectiveContext<DirectivesType>('Directives', directivesDefaultValues)
// Short-hand for <Directive name="title" content={children} />
export const Title = React.memo<{ children: string | null | undefined }>(({ children }) => (
<Directive name="title" content={children} />
))
3. Applying the directives in the layout
To use the directives in the layout, you need to use the useDirectives
hook.
import { useDirectives } from "../Directives"
export const Layout = ({ children: pages }: React.PropsWithChildren) => {
const directives = useDirectives()
return (
<>
<main>
<h1>{directives.title}</h1>
</main>
{pages}
</>
)
}