跳到主要内容

组件属性

分类HooksClasses
属性声明及默认值props=default-valuestatic defaultProps v0.13/ES2022
属性类型及校验TypeScriptstatic propTypes v0.13/ES2022
读取属性值propsthis.props v0.13

大纲

  • 属性
    • 声明
      • 默认值
      • 类型及校验
    • 读取
    • 绑定
    • 透传/传递
    • Children 属性
    • Render 属性

属性声明

  • 属性声明
  • 属性默认值
  • 属性类型及校验(必填)
// React 15.4及以前
// import PropTypes from 'react';
// React v15.5 已弃用
// 已更改从 prop-types 导入
// import PropTypes from 'prop-types';

// TypeScript 支持
// 声明属性类型及校验(必填)
interface Props {
person?: string;
size: number;
}
// ES6 默认参数支持
// 声明属性默认值
export default function Avatar({ person, size = 100 }: Props) {
return (
<h1>Hooks</h1>
)
}

// 声明属性类型及校验(React 19 将移除)
// Avatar.propTypes = {
// person: PropTypes.string.isRequired,
// size: PropTypes.number
// }
// 声明属性默认值及校验(React 19 将移除)
// Avatar.defaultProps = {
// size: 100
// }

export default function Profile() {
return (
// 声明属性
<Avatar person="" size={50} />
)
}

// https://zh-hans.react.dev/learn/passing-props-to-a-component#specifying-a-default-value-for-a-prop
// https://zh-hans.react.dev/blog/2024/04/25/react-19-upgrade-guide#removed-proptypes-and-defaultprops

属性读取

// TypeScript 支持
// 声明属性类型及校验(必填)
interface Props {
person?: string;
size: number;
}

// ES6 “解构” 支持
// ES6 默认参数支持
// 声明属性默认值
// export default function Avatar(props: Props) {
// let person = props.person;
// let size = props.size;
export default function Avatar({ person, size = 100 }: Props) {
return (
// 读取属性
<h1>Hooks {size}</h1>
)
}
// https://zh-hans.react.dev/learn/passing-props-to-a-component#step-2-read-props-inside-the-child-component

属性绑定

JSX 是一种模板语言的最小实现,因为它允许你通过 JavaScript 来组织数据和逻辑。

export default function Profile() {
const other = {
name: 'Gregorio Y. Zara',
theme: {
backgroundColor: 'black',
color: 'pink'
}
};

return (
// 属性绑定
// 使用“引号”传递字符串
// 使用“大括号”传递 JavaScript 变量,大括号内的任何 JavaScript 表达式都能正常运行,包括函数
// 使用“双大括号”传递 JavaScript 对象
<Avatar person="haha" size={50} other={other} />
)
}

属性透传/传递

  • 展开语法 {...props}
export default function Profile(props) {
return (
// ES6 展开符 支持
// 将 Profile 所有的 props 转发给子组件 Avatar
<Avatar {...props} />
)
}
提示

跨层级透传组件属性请查看 context

Children 属性

当你将内容嵌套在 JSX 标签中时,父组件将在名为 children 的 prop 中接收到该内容。

function Card({ children }) {
return (
<div className="card">
{/* children 属性读取 */}
{children}
</div>
);
}

export default function Profile() {
return (
<Card>
{/* children 属性 */}
<Avatar
size={100}
person={{
name: 'Katsuko Saruhashi',
imageId: 'YfeOqp2'
}}
/>
</Card>
);
}

Image

提示

可以将带有 children prop 的组件看作有一个“洞”,可以由其父组件使用任意 JSX 来“填充”。

Render Props

除了为每一个子项生成 JSX,你还可以传递一个返回值类型是 JSX 的函数,并且在必要的时候调用这个函数。

import { useState } from 'react';

export default function TabSwitcher({ tabIds, getHeader, renderContent }) {
const [selectedId, setSelectedId] = useState(tabIds[0]);
return (
<>
{tabIds.map((tabId) => (
<button
key={tabId}
onClick={() => setSelectedId(tabId)}
>
{/* 渲染函数读取 */}
{getHeader(tabId)}
</button>
))}
<hr />
<div key={selectedId}>
{/* 渲染函数读取 */}
<h3>{getHeader(selectedId)}</h3>
{renderContent(selectedId)}
</div>
</>
);
}

export default function App() {
return (
<TabSwitcher
tabIds={['first', 'second', 'third']}
{/* Render Props 渲染属性 */}
getHeader={tabId => {
return tabId[0].toUpperCase() + tabId.slice(1);
}}
{/* Render Props 渲染属性 */}
renderContent={tabId => {
return <p>This is the {tabId} item.</p>;
}}
/>
);
}

渲染属性是函数,所以你可以向它们传递参数。