当前位置: 首页 > wzjs >正文

北京学设计去哪个网站好网站优化服务

北京学设计去哪个网站好,网站优化服务,东莞专业的网站设计价格,做网站为什么能挣钱文章目录 前言✅ 一、什么是 props?✅ 二、props 的特点✅ 三、props 的核心细节 & 常见问题1. **props 是新对象还是引用?**2. **函数作为 props:闭包陷阱**3. **默认值 & 解构默认值**4. **props.children 是什么?**5. …

文章目录

  • 前言
    • ✅ 一、什么是 props?
    • ✅ 二、props 的特点
    • ✅ 三、props 的核心细节 & 常见问题
      • 1. **props 是新对象还是引用?**
      • 2. **函数作为 props:闭包陷阱**
      • 3. **默认值 & 解构默认值**
      • 4. **props.children 是什么?**
      • 5. **props + JSX 组合:可传组件、函数、Slot**
    • 🧠 四、最佳实践
    • ✅ 五、TS 中定义 props
    • ✅ 总结
  • **React 中更高级的 props 设计模式**,
  • 🎯 高级 Props 模式:Render Props、asChild、Slot 模式、函数式 children、Context 替代
    • ✅ 一、Render Props 模式
      • 示例:状态控制组件
      • ✅ 优点:
    • ✅ 二、`asChild` 模式(shadcn/ui 的经典模式)
      • 示例:Button 接收 `asChild` 决定渲染为哪个标签
      • Button 实现:
      • ✅ 优点:
    • ✅ 三、函数式 children 模式(Function-as-Children)
    • ✅ 四、Slot 模式(具名插槽模拟)
    • ✅ 五、Context 替代 Deep Props Drilling
    • 📚 实战建议(封装组件库时)
    • ✅ 总结
    • 📦 安装依赖(如未安装)
    • 🧱 组件结构目录建议:
    • ✅ 1. `components/ui/modal.tsx`
    • ✅ 2. 示例用法 `features/demo-modal.tsx`
    • ✅ 3. 使用 `asChild` 自定义触发器样式
    • ✅ 总结功能支持


前言

在 React 中,props 是组件之间通信的核心机制之一。虽然 props 看起来简单(像参数一样传入组件),但它实际上有许多关键细节和机制,掌握这些对于写出高效、稳定、易维护的 React 组件非常重要。


✅ 一、什么是 props?

props(全称 properties)是组件的“属性”,用于从父组件向子组件传递数据

function Hello({ name }) {return <h1>Hello, {name}!</h1>
}// 使用:
<Hello name="Tom" />

✅ 二、props 的特点

特性说明
📦 只读子组件不能直接修改 props
⛓️ 单向数据流数据只能从父组件流向子组件
🔁 每次 render 都会重新传入props 是受控的,与状态更新同步变化
🧱 支持任意类型可以传入字符串、数字、对象、函数、JSX、组件

✅ 三、props 的核心细节 & 常见问题

1. props 是新对象还是引用?

  • 每次父组件 render,子组件都会收到新的 props 对象引用(即使值不变)。
  • 所以你应该使用 React.memo 来优化子组件避免不必要的重渲染。
const MemoChild = React.memo(({ data }) => { ... })

⚠️ 注意:传入的是对象或函数时,=== 变了就会触发子组件 render。


2. 函数作为 props:闭包陷阱

<Child onClick={() => doSomething()} />

这种写法会在每次父组件渲染时创建新的函数,导致子组件无法 memo 优化。解决方法:

const memoized = useCallback(() => doSomething(), [])
<Child onClick={memoized} />

3. 默认值 & 解构默认值

function Greeting({ name = "Guest" }) {return <h1>Hello, {name}</h1>
}

或者使用默认 props(对于类组件):

MyComponent.defaultProps = {name: 'Guest'
}

⚠️ 对于函数组件推荐解构默认值。


4. props.children 是什么?

props.children组件标签内嵌套的内容

<Panel><p>This is child</p>
</Panel>
function Panel({ children }) {return <div>{children}</div>
}

children 可以是字符串、JSX、数组、函数等。


5. props + JSX 组合:可传组件、函数、Slot

<MyButton renderIcon={() => <Icon />} />

允许传递函数或组件作为 props,实现类似插槽功能。


🧠 四、最佳实践

场景建议
子组件依赖复杂 props 变化React.memo + useCallback 优化
多个 props 逻辑交叉抽象成对象 props:如 config, options
子组件行为复杂用 props 传入回调而不是在组件内部硬编码
渲染内容灵活使用 props.childrenrender prop 模式

✅ 五、TS 中定义 props

type MyProps = {name: stringonClick?: () => voidchildren?: React.ReactNode
}const MyComponent: React.FC<MyProps> = ({ name, onClick, children }) => (<div>{name}</div>
)

✅ 总结

说明
只读组件内部不能修改 props
单向从父 → 子流动,反向用回调
优化使用 memo、useCallback 避免重复渲染
TS 类型用接口定义 props,增强代码可维护性
children支持插槽、嵌套等灵活布局

如果你想了解:

  • props 如何与 contextstate 配合?
  • 如何实现动态 Slot(类似 Vue 的具名插槽)?
  • 或如何设计组件库的高级 props 模式(如 render props、asChild 模式)?

React 中更高级的 props 设计模式

尤其适用于你在封装可复用组件库时的实践需求,包括:


🎯 高级 Props 模式:Render Props、asChild、Slot 模式、函数式 children、Context 替代


✅ 一、Render Props 模式

通过 props 传入一个函数,让子组件决定如何渲染内容。

示例:状态控制组件

const Toggle = ({ children }: { children: (on: boolean, toggle: () => void) => React.ReactNode }) => {const [on, setOn] = useState(false)const toggle = () => setOn(!on)return <>{children(on, toggle)}</>
}// 使用方式
<Toggle>{(on, toggle) => (<button onClick={toggle}>{on ? 'ON' : 'OFF'}</button>)}
</Toggle>

✅ 优点:

  • 父组件控制状态
  • 子组件控制渲染方式(灵活解耦)

✅ 二、asChild 模式(shadcn/ui 的经典模式)

允许你将组件的行为注入到任意 HTML 元素或组件上。

示例:Button 接收 asChild 决定渲染为哪个标签

<Button asChild><Link href="/about">Go to About</Link>
</Button>

Button 实现:

import { Slot } from "@radix-ui/react-slot"const Button = ({ asChild = false, children, ...props }) => {const Comp = asChild ? Slot : 'button'return <Comp {...props} className="btn">{children}</Comp>
}

✅ 优点:

  • 完美兼容无障碍结构 <a> / <Link>
  • 支持组合式组件

✅ 三、函数式 children 模式(Function-as-Children)

render prop 更自然(常用于列表渲染、状态暴露):

<MyList>{(item) => <div key={item.id}>{item.name}</div>}
</MyList>

类似于 Vue 中的具名插槽默认插槽:

<template #default="slotProps">...</template>

✅ 四、Slot 模式(具名插槽模拟)

React 没有官方 Slot,但可以模拟:

type PanelProps = {header: React.ReactNodefooter: React.ReactNodechildren: React.ReactNode
}const Panel = ({ header, footer, children }: PanelProps) => (<div className="panel"><div className="header">{header}</div><div className="body">{children}</div><div className="footer">{footer}</div></div>
)// 使用:
<Panelheader={<h2>Title</h2>}footer={<button>Submit</button>}
><p>Content</p>
</Panel>

✅ 五、Context 替代 Deep Props Drilling

当 props 需要一层一层传下去时,可用 Context 替代

const ThemeContext = createContext("light")function App() {return (<ThemeContext.Provider value="dark"><Layout /></ThemeContext.Provider>)
}function Layout() {return <Header />
}function Header() {const theme = useContext(ThemeContext)return <h1 className={theme}>Theme Header</h1>
}

📚 实战建议(封装组件库时)

目标推荐做法
自定义渲染内容使用 render propchildren 是函数
保留标签结构灵活性使用 asChild + Slot
复杂嵌套内容用具名插槽模式(多个 props 渲染区域)
深度通信用 React Context 提供状态
封装 + 组合使用 Compound Components 模式(Header.Body.Footer)

✅ 总结

模式用途类比 Vue
render prop内容渲染完全交给父组件<slot :data="...">
asChild自定义渲染元素<component :is="...">
props.children默认内容插槽<slot />
Context深层组件通信provide/inject
Slot 模拟多区域结构控制具名 <slot name="...">

下面是一个完整封装的 Modal(模态框)组件示例,结合了:

  • asChild 模式(支持自定义触发按钮)
  • ✅ Slot 模式(支持具名插槽:Header、Body、Footer)
  • shadcn/ui + Radix UI 实现可访问性、动画、组合组件设计

📦 安装依赖(如未安装)

npx shadcn-ui@latest add dialog button

🧱 组件结构目录建议:

components/ui/modal.tsx        ← 模态框主组件封装(含 asChild + slot 模式)features/demo-modal.tsx   ← 示例使用:组合 Header/Body/Footer + 触发按钮

✅ 1. components/ui/modal.tsx

import * as React from "react"
import {Dialog,DialogTrigger,DialogContent,DialogHeader,DialogTitle,DialogDescription,DialogFooter,DialogClose,
} from "@/components/ui/dialog"
import { Slot } from "@radix-ui/react-slot"interface ModalProps {trigger?: React.ReactNodetitle?: React.ReactNodedescription?: React.ReactNodefooter?: React.ReactNodechildren: React.ReactNodeasChild?: boolean
}export function Modal({trigger,title,description,footer,children,asChild = false,
}: ModalProps) {return (<Dialog>{trigger && (<DialogTrigger asChild={asChild}>{trigger}</DialogTrigger>)}<DialogContent>{(title || description) && (<DialogHeader>{title && <DialogTitle>{title}</DialogTitle>}{description && <DialogDescription>{description}</DialogDescription>}</DialogHeader>)}<div className="py-2">{children}</div>{footer && (<DialogFooter>{footer}</DialogFooter>)}</DialogContent></Dialog>)
}

✅ 2. 示例用法 features/demo-modal.tsx

import { Modal } from "@/components/ui/modal"
import { Button } from "@/components/ui/button"export default function DemoModal() {return (<Modaltrigger={<Button>打开模态框</Button>}title="模态框标题"description="这是模态框描述"footer={<><DialogClose asChild><Button variant="outline">取消</Button></DialogClose><Button>确认</Button></>}><p>你可以在这里放任何自定义内容,如表单、提示、嵌套组件等。</p></Modal>)
}

✅ 3. 使用 asChild 自定义触发器样式

<ModalasChildtrigger={<a className="underline cursor-pointer">点我打开</a>}...
>

✅ 总结功能支持

功能实现方式
具名插槽 Header/Body/Footer使用 titledescriptionchildrenfooter props
自定义触发按钮trigger + asChild
支持嵌套组件内容children 支持 JSX
可访问性与焦点管理使用 shadcn/ui Dialog 组件封装

后面可以扩展这个模态框支持:

  • ✅ 异步加载内容(Skeleton)
  • ✅ 表单提交 loading 状态
  • ✅ 动态打开多个 Modal(如嵌套或全局注册)
  • ✅ 在服务端渲染中与 RSC 配合
http://www.dtcms.com/wzjs/317465.html

相关文章:

  • 城子河网站建设常见的网络推广方式有哪些
  • 手机代码网站有哪些问题百度app
  • 梅江区建设局网站北京seo
  • 青岛装修设计公司排名济南网站万词优化
  • wordpress底部栏如何编辑seo工程师
  • 做情网站软文素材库
  • 网站建设方案范本互联网营销的十五种方式
  • 中国小康建设官方网站扬州网络优化推广
  • 做外贸网哪些网站免费百度seo营销推广
  • csharp网站开发保定网站建设报价
  • 做城管试题在那个网站上seo免费诊断
  • 女生学网络工程难吗最优化方法
  • wordpress 手机网站支付宝制作一个网站需要多少费用
  • 做维修家具广告在哪个网站好交换友情链接的目的
  • 学院网站建设的意义武汉seo招聘
  • 北京网站建设百度排名如何进行市场推广
  • 网站建设正版软件友情链接只有链接
  • 长沙php网站建设希爱力双效片
  • 工信部信息备案网站首页江西seo
  • 做购物平台网站客户体验活动搭建个人网站
  • 青岛知名网站建设公司免费推广网站
  • 怎样做网站店铺cilimao磁力猫在线搜索
  • 利用百度网盘自动播放做视频网站如何在百度发布广告信息
  • 网站开发工具的选择2023年的新闻时事热点论文
  • 做有奖竞猜网站违法吗青岛官网seo方法
  • 沅江市住房和建设局网站外贸建站与推广如何做
  • b2b网站怎么做网页友情链接
  • 不允许做企业网站seo搜索引擎优化到底是什么
  • wordpress站点维护百度产品推广怎么收费
  • 做网站还是微信小程序成都疫情最新消息