สร้างเค้าโครงที่ยืดหยุ่นและส่วนประกอบ UI คอมโพสิตโดยไม่จำเป็นต้องกำหนดอุปกรณ์ประกอบฉากแบบกำหนดเองโดยพลการ
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 >
) หมายเหตุ: ส่วนประกอบมาโครมีวัตถุประสงค์เพื่อทำงานกับส่วนประกอบเด็กที่เฉพาะเจาะจง เท่านั้น หากคุณต้องการกำหนด ช่อง ให้ดูส่วนทางเลือกด้านล่าง
บ่อยครั้งที่ดีที่สุดที่จะใช้องค์ประกอบของปฏิกิริยาและ props.children เพื่อสร้าง UI ที่ประกอบด้วยองค์ประกอบหลายอย่าง แต่บางครั้งคุณอาจต้องการสร้างส่วนประกอบคอมโพสิตขนาดใหญ่ขึ้นด้วยโครงสร้างต้นไม้ที่ห่อหุ้มไว้สำหรับเค้าโครงหรือสร้างส่วนประกอบ UI แบบ bootstrap เช่นแผงการ์ดหรือการแจ้งเตือน ห้องสมุดนี้ช่วยให้คุณสร้างส่วนประกอบคอมโพสิตด้วยโครงสร้าง DOM ที่ห่อหุ้มโดยไม่จำเป็นต้องกำหนดอุปกรณ์ประกอบฉากโดยพลการ APIs และทำงานเหมือนกับองค์ประกอบที่ตอบสนองอื่น ๆ
สิ่งนี้สามารถช่วยให้แน่ใจว่าพื้นที่ผิว API ส่วนประกอบของคุณยังคงเล็กและง่ายต่อการบำรุงรักษา
หากคุณพบว่าตัวเองกำลังสร้างส่วนประกอบปฏิกิริยาคอมโพสิตที่ไม่แมปกับโครงสร้างข้อมูลตามที่อธิบายไว้ในการคิดใน React โมดูลนี้มีไว้สำหรับคุณ
Macro(componentsObject)(elementFunction)
ส่งคืนส่วนประกอบ React ด้วย API แบบคอมโพสิตที่เก็บโครงสร้างเค้าโครงต้นไม้
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 >
)วัตถุส่วนประกอบถูกใช้เพื่อกำหนดส่วนประกอบส่วนประกอบแมโครจะยอมรับเป็นเด็ก
ฟังก์ชั่นองค์ประกอบคล้ายกับองค์ประกอบปฏิกิริยา แต่ได้รับวัตถุองค์ประกอบเป็นอาร์กิวเมนต์แรกและอุปกรณ์ประกอบฉากเป็นอันที่สอง วัตถุองค์ประกอบถูกสร้างขึ้นจากลูก ๆ และมีวัตถุประสงค์เพื่อให้องค์ประกอบการห่อหุ้มและโครงสร้างองค์ประกอบง่ายขึ้น
ภายในองค์ประกอบแมโครฟังก์ชันองค์ประกอบจะถูกเรียกด้วยวัตถุองค์ประกอบและอุปกรณ์ประกอบฉาก: 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 >
) )ในการใช้ส่วนประกอบเดียวกันสองครั้งให้เป็นคีย์ที่ไม่ซ้ำกันใน ComponentSoBject
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 > ใบอนุญาต MIT