React Props - REACT教程

React Props

在 React 中,Props(属性)是用于将数据从父组件传递到子组件的机制,Props 是只读的,子组件不能直接修改它们,而是应该由父组件来管理和更新。

state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。这就是为什么有些容器组件需要定义 state 来更新和修改数据。 而子组件只能通过 props 来传递数据。


使用 Props

传递 Props 语法:

<ComponentName propName={propValue} />

以下实例演示了如何在组件中使用 props:

示例代码
functionHelloMessage(props){return<h1>Hello{props.name}!</h1>;}constelement= <HelloMessagename="ez4code"/>;constroot=ReactDOM.createRoot(document.getElementById("root"));root.render(element);

实例中 name 属性通过 props.name 来获取。


默认 Props

你可以通过组件类的 defaultProps 属性为 props 设置默认值,实例如下:

示例代码
classHelloMessageextendsReact.Component{render(){return(<h1>Hello,{this.props.name}</h1>);}}HelloMessage.defaultProps={name:'ez4code'};constelement= <HelloMessage/>;constroot=ReactDOM.createRoot(document.getElementById("root"));root.render(element);

多个 Props

可以传递多个属性给子组件。

示例代码
constUserCard=(props)=>{return(<div><h2>{props.name}</h2><p>Age:{props.age}</p><p>Location:{props.location}</p></div>);};constApp=()=>{return(<UserCard name="Alice"age={25}location="New York"/>);};ReactDOM.render(<App/>,document.getElementById('root'));

propTypes 验证

propTypes 是 React 提供的一种工具,用于对组件的 props 进行类型检查。

可以使用 prop-types 库对组件的 props 进行类型检查。

在 React 中,propTypes 作为组件的一个静态属性来定义。首先,你需要安装 prop-types 包:


npm install prop-types

然后,在你的组件文件中引入 prop-types,并定义 propTypes 属性。下面是一个示例

示例代码
importPropTypes from'prop-types';constGreeting=(props)=>{return<h1>Hello,{props.name}!</h1>;};Greeting.propTypes={name:PropTypes.string.isRequired};constApp=()=>{return(<div><Greeting name="Alice"/>{/* <Greeting />  // 这行代码会导致控制台警告,因为 name 是必需的 */}</div>);};ReactDOM.render(<App/>,document.getElementById('root'));

传递回调函数作为 Props

可以将函数作为 props 传递给子组件,子组件可以调用这些函数来与父组件进行通信。

示例代码
classParentComponentextendsReact.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>);}}constChildComponent=(props)=>{constsendMessage=()=>{props.onMessage('Hello from Child!');};return(<div><button onClick={sendMessage}>Send Message</button></div>);};ReactDOM.render(<ParentComponent/>,document.getElementById('root'));

解构 Props

在函数组件中,可以通过解构 props 来简化代码。

示例代码
constGreeting=({name})=>{return<h1>Hello,{name}!</h1>;};constApp=()=>{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 来获取父组件传递过来的数据。

示例代码
classWebSiteextendsReact.Component{constructor(){super();this.state={name:"易知码",site:"https://www.ez4code.com"}}render(){return(<div><Namename={this.state.name}/><Linksite={this.state.site}/></div>);}}classNameextendsReact.Component{render(){return(<h1>{this.props.name}</h1>);}}classLinkextendsReact.Component{render(){return(<ahref={this.props.site}>{this.props.site}</a>);}}constroot=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 是必须的且是字符串,非字符串类型会自动转换为字符串 :

示例代码
vartitle="易知码";//var title = 123;classMyTitleextendsReact.Component{render(){return(<h1>Hello,{this.props.title}</h1>);}}MyTitle.propTypes={title:PropTypes.string};constroot=ReactDOM.createRoot(document.getElementById("root"));root.render(<MyTitletitle={title}/>);
示例代码
vartitle="易知码";//var title = 123;varMyTitle=React.createClass({propTypes:{title:React.PropTypes.string.isRequired,},render:function(){return<h1>{this.props.title}</h1>;}});constroot=ReactDOM.createRoot(document.getElementById("root"));root.render(<MyTitletitle={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 验证器:

示例代码
importReact from'react';importReactDOM from'react-dom/client';importPropTypes from'prop-types';classMyComponentextendsReact.Component{staticpropTypes={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>);}}constroot=ReactDOM.createRoot(document.getElementById("root"));root.render(<MyComponenttitle="Hello, World!"age={30}isAdmin={true}user={{name:"John Doe",email:"[email protected]"}}items={['Item 1','Item 2','Item 3']}callback={()=>alert('Button clicked!')}options="option1"><p>This is a child element</p></MyComponent>);