HoRain云--React 组件

HoRain云--React 组件 HoRain云小助手个人主页 个人专栏: 《Linux 系列教程》《c语言教程》⛺️生活的理想就是为了理想的生活!⛳️ 推荐前些天发现了一个超棒的服务器购买网站性价比超高大内存超划算忍不住分享一下给大家。点击跳转到网站。专栏介绍专栏名称专栏介绍《C语言》本专栏主要撰写C干货内容和编程技巧让大家从底层了解C把更多的知识由抽象到简单通俗易懂。《网络协议》本专栏主要是注重从底层来给大家一步步剖析网络协议的奥秘一起解密网络协议在运行中协议的基本运行机制《docker容器精解篇》全面深入解析 docker 容器从基础到进阶涵盖原理、操作、实践案例助您精通 docker。《linux系列》本专栏主要撰写Linux干货内容从基础到进阶知识由抽象到简单通俗易懂帮你从新手小白到扫地僧。《python 系列》本专栏着重撰写Python相关的干货内容与编程技巧助力大家从底层去认识Python将更多复杂的知识由抽象转化为简单易懂的内容。《试题库》本专栏主要是发布一些考试和练习题库涵盖软考、HCIE、HRCE、CCNA等目录⛳️ 推荐专栏介绍函数组件src/Welcome.js 文件src/index.js 文件类组件实例实例测试实例React 实例实例解析React 实例复合组件React 实例Props属性基础用法Props 解构Props 的类型Children PropsProps 的不可变性组件的组合与复用组合模式容器组件模式高阶组件思想通过组合实现组件命名规范命名规则文件命名组件的导出与导入默认导出命名导出混合导出组件设计原则1. 单一职责原则2. 保持组件简洁3. 合理使用 Props4. 避免深层嵌套React 组件是构建 React 应用的基本单元可以把组件理解为可复用的、独立的 UI 单元每个组件封装了自己的结构、样式、逻辑和状态。React 组件是构建应用的基石组件可以小到一个按钮也可以大到整个页面。组件可以分为函数组件和类组件。从技术角度讲React 组件就是一个返回 React 元素通常是 JSX的 JavaScript 函数或类。// 最简单的组件 function Hello() { return h1Hello, World!/h1; }将复杂的 UI 拆分成组件树App ├── Header │ ├── Logo │ └── Navigation │ ├── NavItem │ └── NavItem ├── Main │ ├── Sidebar │ └── Content │ ├── Article │ └── Article └── Footer函数组件函数组件是定义组件的一种简洁方法。函数组件是一个接受 props 并返回 React 元素的 JavaScript 函数。基础语法// 方式 1函数声明 function Welcome(props) { return h1Hello, {props.name}/h1; } // 方式 2箭头函数 const Welcome (props) { return h1Hello, {props.name}/h1; }; // 方式 3简化写法单行返回 const Welcome (props) h1Hello, {props.name}/h1;创建一个简单的函数组件src/Welcome.js 文件import React from react;// 定义一个函数组件function Welcome(props) {return h1Hello, {props.name}!/h1;}export default Welcome;在 src/index.js 中渲染该组件src/index.js 文件import React from react;import ReactDOM from react-dom;import ./index.css;import Welcome from ./Welcome;const root ReactDOM.createRoot(document.getElementById(root));// 渲染 Welcome 组件并传递 name 属性root.render(Welcome nameWorld /);这个例子展示了一个接受 name 属性并在页面上显示 Hello, World! 的简单组件。类组件类组件使用 ES6 类语法定义通常用于需要管理状态或使用生命周期方法的情况。基础语法:import React, { Component } from react; class Welcome extends Component { render() { return h1Hello, {this.props.name}/h1; } }创建一个类组件实例import React, { Component } from react;class Welcome extends Component {render() {return h1Hello, {this.props.name}!/h1;}}export default Welcome;在 src/index.js 中渲染该组件实例import React from react;import ReactDOM from react-dom;import ./index.css;import Welcome from ./Welcome;const root ReactDOM.createRoot(document.getElementById(root));// 渲染 Welcome 组件并传递 name 属性root.render(Welcome nameWorld /);测试实例接下来我们封装一个输出 Hello World 的组件组件名为 HelloMessageReact 实例function HelloMessage(props) { return h1Hello World!/h1; } const element HelloMessage /; const root ReactDOM.createRoot(document.getElementById(root)); root.render( element );实例解析1、我们可以使用函数定义了一个组件function HelloMessage(props) { return h1Hello World!/h1; }你也可以使用 ES6 class 来定义一个组件:class Welcome extends React.Component { render() { return h1Hello World!/h1; } }2、const element HelloMessage /为用户自定义的组件。注意原生 HTML 元素名以小写字母开头而自定义的 React 类名以大写字母开头比如 HelloMessage 不能写成 helloMessage。除此之外还需要注意组件类只能包含一个顶层标签否则也会报错。如果我们需要向组件传递参数可以使用this.props对象,实例如下React 实例function HelloMessage(props) { return h1Hello {props.name}!/h1; } const element HelloMessage nameRunoob/; const root ReactDOM.createRoot(document.getElementById(root)); root.render( element );以上实例中name属性通过 props.name 来获取。注意在添加属性时 class 属性需要写成 className for 属性需要写成 htmlFor 这是因为 class 和 for 是 JavaScript 的保留字。复合组件我们可以通过创建多个组件来合成一个组件即把组件的不同功能点进行分离。以下实例我们实现了输出网站名字和网址的组件React 实例function Name(props) { return h1网站名称{props.name}/h1; } function Url(props) { return h1网站地址{props.url}/h1; } function Nickname(props) { return h1网站小名{props.nickname}/h1; } function App() { return ( div Name name菜鸟教程 / Url urlhttp://www.runoob.com / Nickname nicknameRunoob / /div ); } const root ReactDOM.createRoot(document.getElementById(root)); root.render( App / );尝试一下 »实例中 App 组件使用了 Name、Url 和 Nickname 组件来输出对应的信息。Props属性Props 是组件之间传递数据的方式类似于函数的参数。基础用法// 父组件传递 props function App() { return ( div Greeting nameAlice age{25} / Greeting nameBob age{30} / /div ); } // 子组件接收 props function Greeting(props) { return ( div h1Hello, {props.name}!/h1 pAge: {props.age}/p /div ); }Props 解构// 推荐直接解构 function Greeting({ name, age }) { return ( div h1Hello, {name}!/h1 pAge: {age}/p /div ); } // 带默认值的解构 function Button({ text Submit, variant primary, disabled false }) { return ( button className{variant} disabled{disabled} {text} /button ); }Props 的类型Props 可以是任何 JavaScript 值function Demo() { const user { name: Alice, age: 25 }; const numbers [1, 2, 3, 4, 5]; const handleClick () alert(Clicked!); return ( MyComponent // 字符串 titleHello // 数字 count{42} // 布尔值 isActive{true} // 数组 items{numbers} // 对象 user{user} // 函数 onClick{handleClick} // JSX children{pThis is content/p} / ); }Children Props特殊的 props用于传递组件的子内容// 方式 1使用 props.children function Card(props) { return ( div classNamecard div classNamecard-body {props.children} /div /div ); } // 方式 2解构 children function Card({ children, title }) { return ( div classNamecard {title h2{title}/h2} div classNamecard-body{children}/div /div ); } // 使用 function App() { return ( Card titleMy Card pThis is the card content/p buttonClick me/button /Card ); }Props 的不可变性重要原则永远不要修改 props// 错误修改 props function BadComponent(props) { props.name Changed; // 绝对不要这样做 return h1{props.name}/h1; } // 正确将 props 视为只读 function GoodComponent({ name }) { const displayName name.toUpperCase(); // 创建新值 return h1{displayName}/h1; }组件的组合与复用组合模式// 基础组件 function Avatar({ src, alt }) { return img src{src} alt{alt} classNameavatar /; } function UserInfo({ name, email }) { return ( div h3{name}/h3 p{email}/p /div ); } // 组合成复杂组件 function UserCard({ user }) { return ( div classNameuser-card Avatar src{user.avatar} alt{user.name} / UserInfo name{user.name} email{user.email} / /div ); }容器组件模式// 容器组件处理逻辑和状态 function Panel({ title, children, collapsible false }) { const [isOpen, setIsOpen] useState(true); return ( div classNamepanel div classNamepanel-header h2{title}/h2 {collapsible ( button onClick{() setIsOpen(!isOpen)} {isOpen ? Collapse : Expand} /button )} /div {isOpen ( div classNamepanel-content {children} /div )} /div ); } // 使用 function App() { return ( Panel titleSettings collapsible pYour settings here.../p /Panel ); }高阶组件思想通过组合实现// 通用的加载状态包装 function WithLoading({ isLoading, children }) { if (isLoading) { return divLoading.../div; } return children; } // 使用 function UserList({ users, isLoading }) { return ( WithLoading isLoading{isLoading} ul {users.map(user ( li key{user.id}{user.name}/li ))} /ul /WithLoading ); }组件命名规范命名规则// 正确大写字母开头PascalCase function UserProfile() { } function BlogPost() { } function NavBar() { } // 错误小写字母开头 function userProfile() { } // React 会将其视为 HTML 标签文件命名// 推荐的文件结构 src/ ├── components/ │ ├── Button.jsx // 或 Button.js │ ├── UserCard.jsx │ ├── Navigation/ │ │ ├── Navigation.jsx │ │ ├── NavItem.jsx │ │ └── index.js // 导出 Navigation组件的导出与导入默认导出// Button.jsx export default function Button({ text }) { return button{text}/button; } // App.jsx import Button from ./Button;命名导出// components.jsx export function Button({ text }) { return button{text}/button; } export function Input({ value, onChange }) { return input value{value} onChange{onChange} /; } // App.jsx import { Button, Input } from ./components;混合导出// Card.jsx export default function Card({ children }) { return div classNamecard{children}/div; } export function CardHeader({ title }) { return div classNamecard-header{title}/div; } export function CardBody({ children }) { return div classNamecard-body{children}/div; } // App.jsx import Card, { CardHeader, CardBody } from ./Card;组件设计原则1. 单一职责原则每个组件应该只做一件事。// 不好组件做太多事情 function UserDashboard() { // 获取用户数据 // 处理表单 // 显示图表 // 处理导航 // ... } // 好拆分成多个组件 function UserDashboard() { return ( div UserProfile / UserStats / UserActivity / /div ); }2. 保持组件简洁组件代码不应该超过 200-300 行。// 好提取子组件 function ProductCard({ product }) { return ( div classNameproduct-card ProductImage src{product.image} / ProductInfo name{product.name} price{product.price} / ProductActions productId{product.id} / /div ); }3. 合理使用 Props不要传递过多的 props。// 不好props 过多 function User({ name, age, email, address, phone, company, role, ... }) { } // 好使用对象 function User({ user }) { const { name, age, email } user; // ... }4. 避免深层嵌套过深的组件嵌套会导致 props drilling 问题。// 问题props 需要层层传递 App Layout user{user} Sidebar user{user} Menu user{user} MenuItem user{user} / /Menu /Sidebar /Layout /App // 解决使用 Context 或状态管理❤️❤️❤️本人水平有限如有纰漏欢迎各位大佬评论批评指正如果觉得这篇文对你有帮助的话也请给个点赞、收藏下吧非常感谢! Stay Hungry Stay Foolish 道阻且长,行则将至,让我们一起加油吧