Props
Props
在 React 中,Props(属性)是用于将数据从父组件传递到子组件的机制,Props 是只读的,子组件不能直接修改它们,而是应该由父组件来管理和更新。
state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。这就是为什么有些容器组件需要定义 state 来更新和修改数据。 而子组件只能通过 props 来传递数据。
使用 Props
<ComponentName propName={propValue} />
示例
<div id="root"></div>
<script type="text/babel">
function HelloMessage(props) {
return <h1>Hello {props.name}!</h1>;
}
const element = <HelloMessage name="Runoob"/>;
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
element
);
</script>
打印结果: Hello Runoob!
实例中 name 属性通过 props.name 来获取。
默认 Props
你可以通过组件类的 defaultProps 属性为 props 设置默认值,实例如下:
<div id="root"></div>
<script type="text/babel">
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
);
</script>
打印结果: Hello, Runoob
多个 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 验证
propTypes
是 React 提供的一种工具,用于对组件的 props 进行类型检查。
可以使用 prop-types
库对组件的 props 进行类型检查。
在 React 中,propTypes
作为组件的一个静态属性来定义。首先,你需要安装 prop-types
包:
npm install prop-types
然后,在你的组件文件中引入 prop-types
,并定义 propTypes
属性
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 来获取父组件传递过来的数据。
class WebSite extends React.Component {
constructor() {
super();
this.state = {
name: "自学教程",
site: "https://www.baidu.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 />
);

Props 验证
React.PropTypes 在 React v15.5 版本后已经移到了 prop-types 库
Props 验证使用 propTypes,它可以保证我们的应用组件被正确使用,React.PropTypes 提供很多验证器 (validator) 来验证传入数据是否有效。当向 props 传入无效数据时,JavaScript 控制台会抛出警告。
以下实例创建一个 Mytitle 组件,属性 title 是必须的且是字符串,非字符串类型会自动转换为字符串 :
React 16.4 实例
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} />
);
React 15.4 实例
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.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>
);