在 React 中,Props(属性)是用于将数据从父组件传递到子组件的机制,Props 是只读的,子组件不能直接修改它们,而是应该由父组件来管理和更新。
state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。这就是为什么有些容器组件需要定义 state 来更新和修改数据。 而子组件只能通过 props 来传递数据。
传递 Props 语法:
1 |
<ComponentName propName={propValue} /> |
以下实例演示了如何在组件中使用 props:
1 2 3 4 5 6 7 8 9 10 |
function HelloMessage(props) { return <h1>Hello {props.name}!</h1>; } const element = <HelloMessage name="Runoob"/>; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( element ); |
实例中 name 属性通过 props.name 来获取。
你可以通过组件类的 defaultProps 属性为 props 设置默认值,实例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
class HelloMessage extends React.Component { render() { return ( <h1>Hello, {this.props.name}</h1> ); } } HelloMessage.defaultProps = { name: 'Runoob' }; const element = <HelloMessage/>; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( element ); |
可以传递多个属性给子组件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
const UserCard = (props) => { return ( <div> <h2>{props.name}</h2> <p>Age: {props.age}</p> <p>Location: {props.location}</p> </div> ); }; const App = () => { return ( <UserCard name="Alice" age={25} location="New York" /> ); }; ReactDOM.render(<App />, document.getElementById('root')); |
propTypes 是 React 提供的一种工具,用于对组件的 props 进行类型检查。
可以使用 prop-types 库对组件的 props 进行类型检查。
在 React 中,propTypes 作为组件的一个静态属性来定义。首先,你需要安装 prop-types 包:
1 |
npm install prop-types |
然后,在你的组件文件中引入 prop-types,并定义 propTypes 属性。下面是一个示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import PropTypes from 'prop-types'; const Greeting = (props) => { return <h1>Hello, {props.name}!</h1>; }; Greeting.propTypes = { name: PropTypes.string.isRequired }; const App = () => { return ( <div> <Greeting name="Alice" /> {/* <Greeting /> // 这行代码会导致控制台警告,因为 name 是必需的 */} </div> ); }; ReactDOM.render(<App />, document.getElementById('root')); |
可以将函数作为 props 传递给子组件,子组件可以调用这些函数来与父组件进行通信。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
class ParentComponent extends React.Component { constructor(props) { super(props); this.state = { message: '' }; } handleMessage = (msg) => { this.setState({ message: msg }); }; render() { return ( <div> <ChildComponent onMessage={this.handleMessage} /> <p>Message from Child: {this.state.message}</p> </div> ); } } const ChildComponent = (props) => { const sendMessage = () => { props.onMessage('Hello from Child!'); }; return ( <div> <button onClick={sendMessage}>Send Message</button> </div> ); }; ReactDOM.render(<ParentComponent />, document.getElementById('root')); |
在函数组件中,可以通过解构 props 来简化代码。
1 2 3 4 5 6 7 8 9 |
const Greeting = ({ name }) => { return <h1>Hello, {name}!</h1>; }; const App = () => { return <Greeting name="Alice" />; }; ReactDOM.render(<App />, document.getElementById('root')); |
props
接收。defaultProps
设置组件的默认属性值。prop-types
库对 props 进行类型检查。以下实例演示了如何在应用中组合使用 state 和 props 。我们可以在父组件中设置 state, 并通过在子组件上使用 props 将其传递到子组件上。在 render 函数中, 我们设置 name 和 site 来获取父组件传递过来的数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
class WebSite extends React.Component { constructor() { super(); this.state = { name: "菜鸟教程", site: "https://www.runoob.com" } } render() { return ( <div> <Name name={this.state.name} /> <Link site={this.state.site} /> </div> ); } } class Name extends React.Component { render() { return ( <h1>{this.props.name}</h1> ); } } class Link extends React.Component { render() { return ( <a href={this.props.site}> {this.props.site} </a> ); } } const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <WebSite /> ); |
React.PropTypes 在 React v15.5 版本后已经移到了 prop-types 库。
React v19已经移除prop-types 和default prop
1 |
<script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/prop-types/15.8.1/prop-types.min.js" type="application/javascript"></script> |
Props 验证使用 propTypes,它可以保证我们的应用组件被正确使用,React.PropTypes 提供很多验证器 (validator) 来验证传入数据是否有效。当向 props 传入无效数据时,JavaScript 控制台会抛出警告。
以下实例创建一个 Mytitle 组件,属性 title 是必须的且是字符串,非字符串类型会自动转换为字符串 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
var title = "菜鸟教程"; // var title = 123; class MyTitle extends React.Component { render() { return ( <h1>Hello, {this.props.title}</h1> ); } } MyTitle.propTypes = { title: PropTypes.string }; const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <MyTitle title={title} /> ); |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
var title = "菜鸟教程"; // var title = 123; var MyTitle = React.createClass({ propTypes: { title: React.PropTypes.string.isRequired, }, render: function() { return <h1> {this.props.title} </h1>; } }); const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <MyTitle title={title} /> ); |
当然,可以为你介绍更多的 PropTypes
验证器以及如何使用它们。以下是一些常用的 PropTypes
验证器说明:
基本数据类型
PropTypes.string
:字符串PropTypes.number
:数字PropTypes.boolean
:布尔值PropTypes.object
:对象PropTypes.array
:数组PropTypes.func
:函数PropTypes.symbol
:Symbol特殊类型
PropTypes.node
:任何可以被渲染的内容:数字、字符串、元素或数组(包括这些类型)PropTypes.element
:React元素PropTypes.instanceOf(Class)
:某个类的实例组合类型
PropTypes.oneOf(['option1', 'option2'])
:枚举类型,值必须是所提供选项之一PropTypes.oneOfType([PropTypes.string, PropTypes.number])
:多个类型中的一个PropTypes.arrayOf(PropTypes.number)
:某种类型组成的数组PropTypes.objectOf(PropTypes.number)
:某种类型组成的对象PropTypes.shape({ key: PropTypes.string, value: PropTypes.number })
:具有特定形状的对象其他
PropTypes.any
:任何类型PropTypes.exact({ key: PropTypes.string })
:具有特定键的对象,且不能有其他多余的键以下是一些示例代码,展示了如何使用不同的 PropTypes
验证器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
import React from 'react'; import ReactDOM from 'react-dom/client'; import PropTypes from 'prop-types'; class MyComponent extends React.Component { static propTypes = { title: PropTypes.string.isRequired, // 必须是字符串且必需 age: PropTypes.number, // 可选的数字 isAdmin: PropTypes.bool, // 可选的布尔值 user: PropTypes.shape({ // 必须是具有特定形状的对象 name: PropTypes.string, email: PropTypes.string }), items: PropTypes.arrayOf(PropTypes.string), // 必须是字符串数组 callback: PropTypes.func, // 可选的函数 children: PropTypes.node, // 可选的可以渲染的内容 options: PropTypes.oneOf(['option1', 'option2']), // 必须是特定值之一 }; render() { return ( <div> <h1>{this.props.title}</h1> {this.props.age && <p>Age: {this.props.age}</p>} {this.props.isAdmin && <p>Admin</p>} {this.props.user && ( <div> <p>Name: {this.props.user.name}</p> <p>Email: {this.props.user.email}</p> </div> )} {this.props.items && ( <ul> {this.props.items.map((item, index) => ( <li key={index}>{item}</li> ))} </ul> )} {this.props.callback && ( <button onClick={this.props.callback}>Click me</button> )} {this.props.children} {this.props.options && <p>Option: {this.props.options}</p>} </div> ); } } const root = ReactDOM.createRoot(document.getElementById("root")); root.render( <MyComponent title="Hello, World!" age={30} isAdmin={true} user={{ name: "John Doe", email: "john@example.com" }} items={['Item 1', 'Item 2', 'Item 3']} callback={() => alert('Button clicked!')} options="option1" > <p>This is a child element</p> </MyComponent> ); |
from:https://www.runoob.com/react/react-props.html