掌握 React 中的 Props 和 PropTypes

已发表: 2022-03-10
快速总结 ↬ Props 和 PropTypes 是 React 组件之间传递信息的重要机制,我们将在这里详细研究它们。 本教程将向您介绍有关 props、传递和访问 props 以及使用 props 向任何组件传递信息的详细信息。 但是,使用 PropTypes 来验证我们通过 props 获得的数据始终是一个好习惯。 因此,您还将学习如何在 React 中集成 PropTypes。

props 和 PropTypes 会让你感到困惑吗? 你不是一个人。 我将指导您了解有关 props 和 PropTypes 的所有内容。 在开发 React 应用程序时,它们可以让你的生活变得更加轻松。 本教程将向您介绍有关 props、传递和访问 props 以及使用 props 向任何组件传递信息的详细信息。

构建 React 应用程序涉及将 UI 分解为多个组件,这意味着我们需要将数据从一个组件传递到另一个组件。 Props 是 React 组件之间传递信息的重要机制,我们将详细研究它们。 如果不研究 PropTypes,本文将是不完整的,因为它们确保组件使用正确的数据类型并传递正确的数据。

使用 PropTypes 验证我们作为 props 获得的数据始终是一个好习惯。 您还将了解如何在 React 中集成 PropTypes、使用 PropTypes 进行类型检查以及使用 defaultProps。 在本教程的最后,您将了解如何有效地使用 props 和 PropTypes。 重要的是你已经对 React 的工作原理有基本的了解。

了解道具

React 允许我们使用称为 props(属性的缩写)的东西将信息传递给组件。 因为 React 包含多个组件,所以 props 可以在需要它们的组件之间共享相同的数据。 它利用单向数据流(父子组件)。 但是,使用回调函数,可以将 props 从子组件传递回父组件。

这些数据可以有不同的形式:数字、字符串、数组、函数、对象等。我们可以将 props 传递给任何组件,就像我们可以在任何 HTML 标签中声明属性一样。 看看下面的代码:

 <PostList posts={postsList} />

在这个片段中,我们将一个名为posts的 prop 传递给一个名为PostList的组件。 该道具的值为{postsList} 。 让我们分解如何访问和传递数据。

跳跃后更多! 继续往下看↓

传递和访问道具

为了使本教程更有趣,让我们创建一个显示用户名和帖子列表的应用程序。 应用程序演示如下所示:

请参阅 David Adeneye 的 Pen [传递和访问道具](https://codepen.io/smashingmag/pen/MWyKQpd)。

请参阅 David Adeneye 的 Pen Passing and Accessing Props。

该应用程序包含组件集合:一个App组件、一个PostList组件和一个Post组件

帖子列表将需要content和用户name等数据。 我们可以像这样构造数据:

 const postsList = [ { id: 1, content: "The world will be out of the pandemic soon", user: "Lola Lilly", }, { id: 2, content: "I'm really exited I'm getting married soon", user: "Rebecca Smith", }, { id: 3, content: "What is your take on this pandemic", user: "John Doe", }, { id: 4, content: "Is the world really coming to an end", user: "David Mark", }, ];

之后,我们需要App组件来拉取数据,下面是该组件的基本结构:

 const App = () => { return ( <div> <PostList posts={postsList} /> </div> ); };

在这里,我们将一个帖子数组作为道具传递给PostList (稍后我们将创建它)。 父组件PostList将访问postsList中的数据,这些数据将作为posts props 传递给子组件 ( Post )。 如果您还记得,我们的应用程序包含三个组件,我们将在继续进行时创建它们。

让我们创建PostList

 class PostList extends React.Component { render() { return ( <React.Fragment> <h1>Latest Users Posts</h1> <ul> {this.props.posts.map((post) => { return ( <li key={post.id}> <Post {...post} /> </li> ); })} </ul> </React.Fragment> ); } }

PostList组件将接收posts作为其道具。 然后它将循环通过posts道具this.props.posts以将每个发布的项目作为Post组件返回(我们稍后将对其建模)。 另外,请注意上面代码片段中key的使用。 对于那些刚接触 React 的人来说,键是分配给列表中每个项目的唯一标识符,使我们能够区分项目。 在这种情况下,关键是每个帖子的id 。 两个项目不可能有相同的id ,所以这是一个很好的数据用于此目的。

同时,剩余的属性作为 props 传递给Post组件( <Post {...post} /> )。

因此,让我们创建Post组件并使用其中的道具:

 const Post = (props) => { return ( <div> <h2>{props.content}</h2> <h4>username: {props.user}</h4> </div> ); };

我们将Post组件构建为一个函数式组件,而不是像我们为PostList组件所做的那样将其定义为一个类组件。 我这样做是为了向您展示如何访问函数组件中的道具,与我们如何使用this.props在类组件中访问它们进行比较 因为这是一个功能组件,我们可以使用props访问这些值

我们现在已经学习了如何传递和访问 props,以及如何将信息从一个组件传递到另一个组件。 现在让我们考虑一下 props 是如何与函数一起工作的。

通过道具传递函数

在上一节中,我们将一组数据作为 props 从一个组件传递到另一个组件。 但是如果我们使用函数来代替呢? React 允许我们在组件之间传递函数。 当我们想要从其子组件触发父组件的状态更改时,这会派上用场。 道具应该是不可变的; 您不应该尝试更改道具的值。 您必须在传递它的组件中执行此操作,即父组件。

让我们创建一个简单的演示应用程序,它监听点击事件并更改应用程序的状态。 要在不同的组件中更改应用程序的状态,我们必须将函数传递给需要更改状态的组件。 这样,我们的子组件中就会有一个能够改变状态的函数。

听起来有点复杂? 我创建了一个简单的 React 应用程序,它通过单击按钮更改状态并呈现一条欢迎信息:

请参阅 David Adeneye 的 Pen [通过 React 中的 Props 传递函数](https://codepen.io/smashingmag/pen/WNwrMEY)。

请参阅 David Adeneye 的通过 Props in React 的 Pen Passing Function。

在上面的演示中,我们有两个组件。 一种是App组件,它是包含应用程序状态和设置状态的函数的父组件。 ChildComponent将是这个场景中的子组件,它的任务是在状态改变时呈现欢迎信息。

让我们把它分解成代码:

 class App extends React.Component { constructor(props) { super(props); this.state = { isShow: true, }; } toggleShow = () => { this.setState((state) => ({ isShow: !state.isShow })); }; render() { return ( <div> <ChildComponent isShow={this.state.isShow} clickMe={this.toggleShow} /> </div> ); } }

请注意,我们已将状态设置为true ,并且在App组件中创建了更改状态的方法。 在render()函数中,我们将应用程序的状态作为 prop isShow传递给ChildComponent组件。 我们还将toggleShow()函数作为名为clickMe的道具传递。

我们将在ChildComponent中使用它,如下所示:

 class ChildComponent extends React.Component { clickMe = () => { this.props.clickMe(); }; render() { const greeting = "Welcome to React Props"; return ( <div style={{ textAlign: "center", marginTop: "8rem" }}> {this.props.isShow ? ( <h1 style={{ color: "green", fontSize: "4rem" }}>{greeting}</h1> ) : null} <button onClick={this.clickMe}> <h3>click Me</h3> </button> </div> ); } }

上面最重要的是App组件将一个函数作为 prop 传递给ChildComponent 。 函数clickMe()用于ChildComponent中的单击处理程序,而ChildComponent不知道函数的逻辑 - 它仅在单击按钮时触发函数。 调用函数时状态会发生变化,一旦状态发生变化,状态就会再次作为道具向下传递。 所有受影响的组件,例如我们案例中的子组件,将再次渲染。

我们必须将应用程序的状态isShow作为道具传递给ChildComponent ,因为没有它,我们无法编写上面的逻辑来在状态更新时显示greeting

现在我们已经了解了函数,让我们转向验证。 使用 PropTypes 验证我们通过 props 获得的数据始终是一个好习惯。 现在让我们深入研究一下。

React 中的 PropType 是什么?

PropTypes 是一种机制,可确保组件使用正确的数据类型并传递正确的数据,并且组件使用正确类型的 props,并且接收组件接收正确类型的 props。

我们可以把它想象成一只小狗被送到宠物店。 宠物店不想要猪、狮子、青蛙或壁虎——它想要小狗。 PropTypes 确保正确的数据类型(小狗)被传递到宠物店,而不是其他种类的动物。

在上面的部分中,我们看到了如何使用 props 将信息传递给任何组件。 我们直接将 props 作为属性传递给组件,我们还从组件外部传递 props 并在该组件中使用它们。 但是我们没有检查我们通过 props 在我们的组件中获得了什么类型的值,或者一切仍然有效。

是否通过 props 验证我们在组件中获得的数据完全取决于我们。 但在复杂的应用程序中,验证数据始终是一种好习惯。

使用 PropType

要使用 PropTypes,我们必须通过 npm 或 Yarn 将包作为依赖项添加到我们的应用程序中,方法是在命令行中运行以下代码。 对于 npm:

 npm install --save prop-types

对于纱线:

 yarn add prop-types

要使用 PropTypes,我们首先需要从 prop-types 包中导入 PropTypes:

 import PropTypes from 'prop-types';

让我们在我们的应用程序中使用 ProTypes 来列出用户的帖子。 下面是我们将如何将它用于Post组件:

 Post.proptypes = { id: PropTypes.number, content: PropTypes.string, user: PropTypes.string }

在这里, PropTypes.stringPropTypes.number是 prop 验证器,可用于确保收到的 props 是正确的类型。 在上面的代码中,我们声明id是一个数字,而contentuser是字符串。

此外,PropTypes 在捕捉错误方面很有用。 我们可以使用isRequired强制传递道具:

 Post.proptypes = { id: PropTypes.number.isRequired, content: PropTypes.string.isRequired, user: PropTypes.string.isRequired }

PropTypes 有很多验证器。 以下是一些最常见的:

 Component.proptypes = { stringProp: PropTypes.string, // The prop should be a string numberProp: PropTypes.number, // The prop should be a number anyProp: PropTypes.any, // The prop can be of any data type booleanProp: PropTypes.bool, // The prop should be a function functionProp: PropTypes.func // The prop should be a function arrayProp: PropTypes.array // The prop should be an array }

有更多类型可用,您可以查看 React 的文档]。

默认道具

如果我们想使用 props 将一些默认信息传递给我们的组件,React 允许我们使用名为defaultProps的东西来做到这一点。 如果 PropTypes 是可选的(也就是说,它们不使用isRequired ),我们可以设置defaultProps 。 默认 props 确保 props 有一个值,以防万一没有通过。 这是一个例子:

 Class Profile extends React.Component{ // Specifies the default values for props static defaultProps = { name: 'Stranger' }; // Renders "Welcome, Stranger": render() { return <h2> Welcome, {this.props.name}<h2> } }

在这里, defaultProps将用于确保this.props.name有一个值,以防父组件未指定它。 如果没有将名称传递给类Profile ,那么它将具有默认属性Stranger以供使用。 这可以防止在没有传递任何道具时出现任何错误。 我建议您始终对每个可选的 PropType 使用defaultProps

结论

我希望您喜欢本教程。 希望它向您展示了 props 和 propTypes 对于构建 React 应用程序的重要性,因为没有它们,我们将无法在交互发生时在组件之间传递数据。 它们是 React 围绕组件驱动和状态管理架构设计的核心部分。

PropTypes 是一个奖励,它确保组件使用正确的数据类型并传递正确的数据,组件使用正确类型的 props,以及接收组件接收正确类型的 props。

如果您有任何问题,可以将它们留在下面的评论部分,我很乐意回答每个问题并与您一起解决任何问题。

参考

  • “在 React 中思考”,React 文档
  • “列表和键”,React 文档
  • “使用 PropTypes 进行类型检查”,React 文档
  • “如何在 React 中将道具传递给组件”,Robin Wieruch