React Props
在 React 中,Props(属性)是用于将数据从父组件传递到子组件的机制,Props 是只读的,子组件不能直接修改它们,而是应该由父组件来管理和更新。
state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。这就是为什么有些容器组件需要定义 state 来更新和修改数据。 而子组件只能通过 props 来传递数据。
使用 Props
传递 Props 语法:
<ComponentName propName={propValue} />
以下实例演示了如何在组件中使用 props:
React 实例
function HelloMessage ( props ) { return < h1 > Hello { props . name } !</ h1 >; } const element = < HelloMessage name = " thltools " />; const root = ReactDOM . createRoot ( document . getElementById ( " root " ) ) ; root . render ( element ) ;
实例中 name 属性通过 props.name 来获取。
默认 Props
你可以通过组件类的 defaultProps 属性为 props 设置默认值,实例如下:
React 实例
class HelloMessage extends React . Component { render ( ) { return ( < h1 > Hello , { this . props . name } </ h1 > ) ; } } HelloMessage . defaultProps = { name : ' thltools ' } ; const element = < HelloMessage />; const root = ReactDOM . createRoot ( document . getElementById ( " root " ) ) ; root . render ( element ) ;
多个 Props
可以传递多个属性给子组件。
实例
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 验证
可以使用 prop-types 库对组件的 props 进行类型检查。
实例
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
可以将函数作为 props 传递给子组件,子组件可以调用这些函数来与父组件进行通信。
实例
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
在函数组件中,可以通过解构 props 来简化代码。
实例
const Greeting = ( { name } ) => {
return <h1 >Hello , {name } !</h1 >;
} ;
const App = ( ) => {
return <Greeting name = "Alice" />;
} ;
ReactDOM. render ( <App />, document. getElementById ( 'root' ) ) ;
小结
- 传递和使用 Props:父组件传递数据给子组件,子组件通过
props
接收。
- 默认 Props:使用
defaultProps
设置组件的默认属性值。
- PropTypes 验证:使用
prop-types
库对 props 进行类型检查。
- 传递回调函数:父组件可以将函数作为 props 传递给子组件,以实现组件间通信。
- 解构 Props:在函数组件中解构 props 以简化代码。
State 和 Props
以下实例演示了如何在应用中组合使用 state 和 props 。我们可以在父组件中设置 state, 并通过在子组件上使用 props 将其传递到子组件上。在 render 函数中, 我们设置 name 和 site 来获取父组件传递过来的数据。
React 实例
class WebSite extends React . Component { constructor ( ) { super ( ) ; this . state = { name : " thltools教程 " , site : " https://www.thltools.cn " } } 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 /> ) ;
Props 验证
React.PropTypes 在 React v15.5 版本后已经移到了 prop-types 库。
<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 是必须的且是字符串,非字符串类型会自动转换为字符串 :
React 16.4 实例
var title = " thltools教程 " ; 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 } /> ) ;
React 15.4 实例
var title = " thltools教程 " ; 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
验证器:
实例
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 >
) ;