@yandex/ui
Version:
Yandex UI components
118 lines (91 loc) • 3.62 kB
Markdown
# render-override
Библиотека, предоставляющая набор хуков и компонентов для реализации переопределения элементов внутри составного компонента.
## Мотивация
Зачастую компоненты, даже примитивные, состоят из нескольких элементов и невозможно предусмотреть заранее все варианты использования и описать для этого интерфейс поэтому необходим механизм, который позволит дополнять или заменять необходимую часть компонента.
## Использование
В зависимости от типа компонента используйте подходящий вариант:
**functional component**
```tsx
import React from 'react'
import { useRenderOverride } from '@yandex-lego/components/lib/render-override'
const ElementOriginal = ({ children }) => <div>{children}</div>
const MyComponent = ({ renderElement }) => {
const Element = useRenderOverride(ElementOriginal, renderElement)
return (
<>
<Element />
</>
)
}
```
**classes component (single component)**
```tsx
import React from 'react'
import { RenderOverrideProvider } from '@yandex-lego/components/lib/render-override'
const ElementOriginal = ({ children }) => <div>{children}</div>
const MyComponent = ({ renderElement }) => (
<>
<RenderOverrideProvider component={ElementOriginal} render={renderElement}>
{(Element) => <Element />}
</RenderOverrideProvider>
</>
)
```
**classes component (multi components)**
```tsx
import React from 'react'
import { MultiRenderOverrideProvider } from '@yandex-lego/components/lib/render-override'
const ElementOriginal1 = ({ children }) => <div>{children}</div>
const ElementOriginal2 = ({ children }) => <div>{children}</div>
const MyComponent = ({ renderElement1, renderElement2 }) => (
<>
<MultiRenderOverrideProvider
components={[
[ElementOriginal2, renderElement1],
[ElementOriginal2, renderElement2],
]}
>
{(Element1, Element2) => (
<>
<Element1 />
<Element2 />
</>
)}
</MultiRenderOverrideProvider>
</>
)
```
**Использование**
```tsx
import React, { useCallback } from 'react'
const App = () => {
// Для лучшей производительности рекомендуется использовать мемоизацию.
// prettier-ignore
const onRenderElement = useCallback((props) => (
<OverridenElement {...props} />
), [])
return (
<>
{/* Полное переопределение элемента. */}
<MyComponent renderElement={onRenderElement} />
{/* Частичное переопределение элемента. */}
<MyComponent
renderElement={(props, Element) => (
<Element {...props} children="overriden children" />
)}
/>
</>
)
}
```
## Соглашение
Все свойства для переопределяемых элементов должны называться со слова `render` и реализовывать `RenderOverride` интерфейс:
```ts
import { RenderOverride } from '@yandex-lego/components/lib/render-override'
type MyComponentProps = {
/**
* Переопределяет компонент `Element`
*/
renderElement?: RenderOverride
}
```