إنشاء تخطيط مرن ومكونات واجهة المستخدم المركبة دون الحاجة إلى تحديد الدعائم المخصصة التعسفية.
npm i macro-components
import React from 'react'
import styled from 'styled-components'
import Macro from 'macro-components'
import { space , fontSize , color } from 'styled-system'
// Define some styled-components
const Box = styled . div ` ${ space } ${ fontSize } ${ color } `
Box . displayName = 'Box'
const Image = styled . img `
max-width: 100%;
height: auto;
${ space }
`
Image . displayName = 'Image'
const Heading = styled . h2 ` ${ space } ${ fontSize } ${ color } `
Heading . displayName = 'Heading'
const Text = styled . div ` ${ space } ${ fontSize } ${ color } `
Text . displayName = 'Text'
// create a macro function with the UI components you intend to use
const macro = Macro ( {
Image ,
Heading ,
Text
} )
// Create a macro-component
const MediaObject = macro ( ( {
Image ,
Heading ,
Text
} ) => (
< Flex p = { 2 } align = 'center' >
< Box width = { 128 } >
{ Image }
</ Box >
< Box >
{ Heading }
{ Text }
</ Box >
</ Flex >
) ) import MediaObject from './MediaObject'
// get the macro component's child components
const { Image , Heading , Text } = MediaObject
// Use the macro-component by passing the components as children
const App = props => (
< div >
< MediaObject >
< Image src = 'kitten.png' />
< Heading >
Hello
</ Heading >
< Text >
This component keeps its tree structure but still allows for regular composition.
</ Text >
</ MediaObject >
</ div >
) ملاحظة: تهدف مكونات الماكرو إلى العمل فقط مع مكونات الأطفال المحددة. إذا كنت ترغب في تحديد الفتحات ، راجع قسم البدائل أدناه.
غالبًا ما يكون من الأفضل استخدام تكوين React و props.children . تتيح لك هذه المكتبة إنشاء مكونات مركبة مع هياكل DOM مغلفة دون الحاجة إلى تحديد واجهات برمجة تطبيقات الدعائم التعسفية والتي تعمل تمامًا مثل أي تكوين رد فعل آخر.
يمكن أن يساعد ذلك في ضمان أن مساحة سطح API المكونة تظل صغيرة وأسهل في الحفاظ عليها.
إذا وجدت نفسك تقوم بإنشاء مكونات رد فعل مركبة لا تخطط لهياكل البيانات ، كما هو موضح في التفكير في React ، فإن هذه الوحدة مخصصة لك.
Macro(componentsObject)(elementFunction)
إرجاع مكون رد الفعل باستخدام واجهة برمجة تطبيقات قابلة للتكامل يحافظ على بنية تخطيط الأشجار.
const Banner = Macro ( {
// pass a components object
Heading ,
Subhead
} ) ( ( {
// the element function receives child elements
// named according to the components object
Heading ,
Subhead
} ) => (
< Box p = { 3 } color = 'white' bg = 'blue' >
{ Heading }
{ Subhead }
</ Box >
) يتم استدعاء وسيطة elementFunction مع كائن من العناصر بناءً على componentsObject التي تم تمريرها إلى وظيفة الماكرو. سيؤدي استخدام مكون اللافتة أعلاه إلى شيء مثل ما يلي.
import Banner from './Banner'
const App = ( ) => (
< Banner >
< Banner . Heading > Hello </ Banner . Heading >
< Banner . Subhead > Subhead </ Banner . Subhead >
</ Banner >
)يتم استخدام كائن المكونات لتحديد المكونات التي سيقبلها مكون الماكرو كأطفال.
تشبه وظيفة العنصر مكون React ، ولكنه يتلقى كائن عناصر كوسيطة أولى ودعائمها كثاني. يتم إنشاء كائن العناصر من أطفاله ويهدف إلى جعل تركيبات التكوين وهياكل العناصر أسهل.
ضمن مكون الماكرو ، يتم استدعاء وظيفة العنصر مع كائن العناصر والدعائم: elementFunction(elementsObject, props) .
// example
const elFunc = ( { Heading , Text , } , props ) => (
< header >
{ Heading }
{ Text }
</ header >
)
const Heading = styled . h2 ``
const Text = styled . div ``
const componentsObj = {
Heading ,
Text
}
const SectionHeader = Macro ( componentsObj ) ( elFunc ) لأي عنصر لم يتم تمريره كطفل إلى مكون الماكرو ، ستجعل وظيفة العنصر undefined ولن تقدم هذا العنصر. هذا مفيد لحذف الأطفال الاختياري بشكل مشروط
const macro = Macro ( { Icon , Text , CloseButton } )
const Message = macro ( {
Icon ,
Text ,
CloseButton
} ) = > (
< Flex p = { 2 } bg = 'lightYellow' >
{ Icon }
{ Text }
< Box mx = 'auto' />
{ CloseButton }
</ Flex >
) import Message from './Message'
const { Text , CloseButton } = Message
// Omitting the Icon child element will render Message without an icon.
const message = (
< Message >
< Text > { props . message } </ Text >
< CloseButton
onClick = { props . dismissMessage }
/>
</ Message >
)تتيح لك الوسيطة الثانية التي تم تمريرها إلى وظيفة العنصر تمرير الدعائم إلى عنصر الجذر أو أي عنصر آخر داخل المكون.
const macro = Macro ( { Image , Text } )
const Card = macro ( ( {
Image ,
Text
} , props ) => (
< Box p = { 2 } bg = { props . bg } >
{ Image }
{ Text }
</ Box >
) ) // example usage
< Card bg = 'tomato' >
< Card . Image src = 'kittens.png' />
< Card . Text > Meow </ Card . Text >
</ Card >لتطبيق الدعائم الافتراضية على العناصر التي تم تمريرها كأطفال ، استخدم مكون الاستنساخ في وظيفة عنصر.
import Macro , { Clone } from 'macro-components'
import { Heading , Text } from './ui'
const macro = Macro ( { Heading , Text } )
const Header = macro ( ( { Heading , Text } ) => (
< Box p = { 2 } >
< Clone
element = { Heading }
fontSize = { 6 }
mb = { 2 }
/>
< Clone
element = { Text }
fontSize = { 3 }
/>
</ Box >
) )لاستخدام نفس المكون مرتين ، امنحه مفتاحًا فريدًا في المكونات.
import React from 'react'
import Macro from 'macro-components'
import { Heading } from './ui'
const macro = Macro ( {
Heading : Heading ,
Subhead : Heading
} )
const Header = macro ( ( { Heading , Subhead } ) => (
< Box p = { 2 } >
{ Heading }
{ Subhead }
</ Box >
) ) < Header >
< Header . Heading > Hello </ Header . Heading >
< Header . Subhead > Subhead </ Header . Subhead >
</ Header >لإنشاء مكونات تخطيط غير مقترنة بمكونات الأطفال المحددة ، ربما يكون استخدام الدعائم أو الأطفال المطلوبة طريقة أبسط.
تتيح لك الحلول أدناه تمرير أي مكونات تعسفية كدعائم أو أطفال.
انظر هذا المناقشة للمزيد.
// using custom props
const MyLayout = ( {
left ,
right
} ) => (
< Flex >
< Box width = { 128 } >
{ left }
</ Box >
< Box width = { 1 } >
{ right }
</ Box >
</ Flex >
)
< MyLayout
left = { (
< Image src = 'kitten.png' />
) }
right = { (
< Text > Meow </ Text >
) }
/ > // using ordered children
const Header = props => {
const [ first , second ] = React . Children . toArray ( props . children )
return (
< Box p = { 3 } >
{ first }
{ second }
</ Box >
)
}
< Header >
< Heading > First </ Heading >
< Text > Second < / Text>
</ Header > // using a children object
const Header = ( {
children : {
left ,
right
}
} ) => (
< Flex >
< Box >
{ left }
</ Box >
< Box width = { 1 } >
{ right }
</ Box >
</ Flex >
)
< Header >
{ {
left : (
< Image src = 'kitten.png' />
) ,
right : (
< Text > Meow </ Text >
)
} }
</ Header > رخصة معهد ماساتشوستس للتكنولوجيا