React Native - 属性 (Props)
React Native - Props
Section titled “React Native - Props”在 React 中,组件主要通过 props(properties 的缩写,意为属性)进行通信和共享数据。Props 是只读的,并从父组件传递给子组件,实现了数据的单向(unidirectional)流动。
本章在理解 state 的基础上,演示如何将数据和函数作为 props 传递。通常会将管理 state 和逻辑的“容器(智能)”组件与主要负责显示数据的“展示(木偶)”组件区分开来。
管理 State 的父(容器)组件
Section titled “管理 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对象。
接收 Props 的子(展示)组件
Section titled “接收 Props 的子(展示)组件”现在,让我们创建 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 不总是传递,可以定义默认 propsChildDisplayComponent.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,并导致两个组件使用新数据重新渲染。
Props 的核心概念
Section titled “Props 的核心概念”- 只读(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