Skip to content

React Native - 属性 (Props)

在 React 中,组件主要通过 props(properties 的缩写,意为属性)进行通信和共享数据。Props 是只读的,并从父组件传递给子组件,实现了数据的单向(unidirectional)流动。

本章在理解 state 的基础上,演示如何将数据和函数作为 props 传递。通常会将管理 state 和逻辑的“容器(智能)”组件与主要负责显示数据的“展示(木偶)”组件区分开来。

让我们创建一个父组件,它包含一些 state 和一个更新 state 的函数。然后它将这些 state 和函数通过 props 传递给子组件。

ParentComponent.js

import React, { useState } from 'react';
import { View, StyleSheet, Text } from 'react-native';
import ChildDisplayComponent from './ChildDisplayComponent'; // 我们接下来会创建它
const ParentComponent = () => {
const [greeting, setGreeting] = useState('Hello from Parent!');
const [count, setCount] = useState(0);
const updateGreeting = (newGreeting) => {
setGreeting(newGreeting);
};
const incrementCount = () => {
setCount(prevCount => prevCount + 1);
};
return (
<View style={styles.container}>
<Text style={styles.parentText}>Parent Component Area</Text>
<ChildDisplayComponent
message={greeting}
currentCount={count}
onUpdateGreeting={updateGreeting} // 传递函数本身
onIncrement={incrementCount} // 传递函数本身
user={{ name: 'Alice', role: 'Admin' }} // 传递一个对象作为 prop
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
backgroundColor: '#e0f7fa',
alignItems: 'center',
},
parentText: {
fontSize: 20,
fontWeight: 'bold',
marginBottom: 15,
color: '#00796b',
}
});
export default ParentComponent;

在 ParentComponent.js 中:

  • 我们使用 useState 管理 greeting 和 count。
  • updateGreeting 和 incrementCount 是修改这些 state 的函数。
  • 我们渲染 ChildDisplayComponent 并通过 props 传递 greeting(作为 message)、count(作为 currentCount)、updateGreeting(作为 onUpdateGreeting)、incrementCount(作为 onIncrement)以及一个 user 对象。

现在,让我们创建 ChildDisplayComponent。此组件将通过其 props 接收数据和函数,并使用它们来渲染 UI 和触发父组件中的操作。

ChildDisplayComponent.js

import React from 'react';
import { Text, View, Button, StyleSheet } from 'react-native';
import PropTypes from 'prop-types'; // 推荐用于 props 的类型检查
// Props 作为第一个参数接收(通常命名为 'props')
// 我们可以在函数签名中直接解构它们
const ChildDisplayComponent = ({ message, currentCount, onUpdateGreeting, onIncrement, user }) => {
return (
<View style={styles.childContainer}>
<Text style={styles.messageText}>Message from parent: {message}</Text>
<Text style={styles.countText}>Current Count: {currentCount}</Text>
<Text style={styles.userInfo}>User: {user.name} ({user.role})</Text>
<Button
title="Update Greeting in Parent"
onPress={() => onUpdateGreeting('Hello from Child!')}
/>
<View style={{ marginTop: 10 }} /> {/* 简单的间隔 */}
<Button
title="Increment Count in Parent"
onPress={onIncrement} // 调用通过 props 传递的函数
/>
</View>
);
};
// PropTypes 定义组件期望的 props 类型。
// 这是捕获 bug 和用于文档的好做法。
ChildDisplayComponent.propTypes = {
message: PropTypes.string.isRequired,
currentCount: PropTypes.number.isRequired,
onUpdateGreeting: PropTypes.func.isRequired,
onIncrement: PropTypes.func.isRequired,
user: PropTypes.shape({
name: PropTypes.string.isRequired,
role: PropTypes.string
}).isRequired
};
// 如果某些 props 不总是传递,可以定义默认 props
ChildDisplayComponent.defaultProps = {
user: { name: 'Guest', role: 'Viewer' } // 如果未提供 'user' prop,将使用此默认值
};
const styles = StyleSheet.create({
childContainer: {
marginTop: 20,
padding: 15,
backgroundColor: '#ffffff',
borderWidth: 1,
borderColor: '#004d40',
borderRadius: 8,
alignItems: 'center',
},
messageText: {
fontSize: 18,
color: '#00796b',
marginBottom: 10,
},
countText: {
fontSize: 18,
color: '#00796b',
marginBottom: 10,
}, userInfo: {
fontSize: 16,
color: '#333',
marginBottom: 20,
}
});
export default ChildDisplayComponent;

在 ChildDisplayComponent.js 中:

  • 它接收 message、currentCount、onUpdateGreeting、onIncrement 和 user 作为 props。
  • 它显示 message、currentCount 和 user 数据。
  • 按钮按下时,会调用从父组件传递下来的函数(onUpdateGreeting、onIncrement)。这使得子组件能够触发父组件中的 state 变化。

当您运行 ParentComponent 时,它将渲染 ChildDisplayComponent。子组件将显示初始的问候语和计数。点击子组件中的按钮将调用父组件中的函数,更新父组件的 state,并导致两个组件使用新数据重新渲染。

  • 只读(Read-Only):组件绝不能修改自己的 props。它们属于父组件。
  • 数据流(Data Flow):数据从父组件向下流向子组件。要从子组件改变父组件中的数据,需要将一个回调函数从父组件传递给子组件。
  • PropTypes:对于大型应用,强烈建议使用 prop-types 库(或 TypeScript)来定义期望的 props 类型,以便尽早发现错误。
  • 默认 Props(Default Props):您可以为那些不是总由父组件提供的 props 定义默认值。

这种由容器组件管理 state 和逻辑,展示组件专注于 UI 并通过 props 接收数据的模式,有助于创建更易于维护和可重用的 React Native 应用。了解更多关于组件和 props 的信息:https://react.dev/learn/passing-props-to-a-component