React props vs state - 差异和设计模式

Irakli Tchigladze 2023年1月30日 2022年5月18日
  1. React state
  2. React props
  3. React 中 stateprops 之间的连接
  4. 在 React 中何时使用 stateprops
React props vs state - 差异和设计模式

React 是最容易学习的 JavaScript 框架之一。但是,这个库引入了一些乍一看似乎令人困惑的概念。例如,许多新手很难理解 propsstate 之间的区别。在本文中,你将了解为什么这两个对象都是必需的,以及如何找到它们的最佳用途。

React state

状态的概念并不是 React 或其他使用它的 JavaScript 框架所独有的。甚至一些用普通 JavaScript 构建的应用程序也可以有一个状态。在 React 中,这个概念有点不同,但基于相同的原则。

每个 React 组件都维护其本地状态对象。状态管理发生在内部。状态对象是可变的;改变它是开发动态 React 组件的关键,这些组件可以响应用户的操作而改变。

父组件不能改变其子组件的状态。你可以将状态值视为普通 JavaScript 函数中的局部变量。这些变量仅限于函数作用域。

在 React 中,状态对象的主要目的是简化为我们的动态应用程序提供动力的所有数据的维护。状态对象值的任何更改都将触发组件的重新渲染。这样,当用户输入发生变化时,用户的视图将始终立即更新。

React props

props(属性的缩写)对象用于与其子组件共享父组件的数据。你可以将 props 视为传递给组件以自定义其行为的设置。想象一下,你有一个渲染视觉效果的 <Bargraph/> 组件。此类组件需要数字来呈现图形。每个图都呈现不同的数据,这些数据可以通过 props 输入它们。这只是 props 如何促进组件可重用性的一个例子。

每个组件都会收到一个 props 对象,该对象在组件内是不可变的。然而,就像你可以将不同的参数传递给函数一样,同一组件的许多实例可以通过 props 接收不同的值。

在幕后,React 使用 React.createElement() 方法来创建 React 组件并传递 props。然而,React 开发人员倾向于使用更熟悉的 JSX 语法来构建 React 应用程序。这种类似 HTML 的语法提供了一种更易读的方式来传递 props

const Graph=(props)=>
{
  return <div>
          <h1>{props.data.percentage}%</h1>
         </div>;
}
class App extends Component {
  constructor(props){
    super(props)
    this.state = {
      data: {percentage: "70"}
    }
  }
  render() {
    return <Graph data={this.state.data}>Hi! Try edit me</Graph>;
  }
}

这是一个相当简单的 props 如何工作的演示。首先,我们定义一个子组件。如你所见,子组件不维护其状态。它只读取通过 props 传递给它的数据。

接下来,我们有一个父组件。与子组件不同,它使用来自其 state 对象的数据将其作为 prop 传递。如你所见,JSX 语法与常规 HTML 不同。

React props 解构

正如你在上面的例子中看到的,每个功能组件都接受一个 props 参数。可以通过读取与 JSX 中的属性同名的属性来访问存储在 props 对象中的数据。

一种更简单的方法是在函数定义中解构 props。这是一个带有解构 props 的 Graph 功能组件的示例:

const Graph=({data = { percentage: 50 } })=>
{
  return <div>
          <h1>{{data.percentage}}%</h1>
         </div>;
}

这允许你使用更简单的语法,甚至可以设置默认的 prop 值。如果子组件没有收到任何 props,组件可以读取默认值。

React 中 stateprops 之间的连接

正如我们之前提到的,在 React 组件中,props 对象是严格不可变的。但是,有一个警告:子组件可以改变父组件中的状态,父组件用作通过 props 传递回子组件的数据源。如果这很难理解,让我们检查一下这个代码示例:

const Graph=(props)=>
{
  const {handler, color} = props
  return <div 
         style={{width: "400px", height: "400px", border: "2px solid black", backgroundColor: `${color}`}}>                     
         <h1>{props.data.percentage}%</h1>
         <input type="text" onChange={(e) => handler(e)}/>
         </div>;
}
class App extends Component {
  constructor(props){
    super(props)
    this.state = {
      data: {percentage: "70"},
      bgColor: "black"
    }
  }
  render() {
    const backgroundHandler = (e) => this.setState({color: e.target.value})     
    return <Graph data={this.state.data} color={this.state.bgColor} handler={backgroundHandler}>
            Hi! Try edit me</Graph>;
  }
}

在这个例子中,我们仍然有我们之前使用的相同的两个组件。我们通过 props 传递一个事件处理程序。然后我们使用相同的处理程序来更新父组件状态中的 color 属性。一旦父组件状态中的值发生更改,它将重新渲染并将更新的颜色值传递回我们的子组件。

这看起来像是子组件更新了它自己的 props,但在这个例子中,它实际上使用通过 props 传递的事件处理程序来更新它自己的 props 的源 - 父组件状态中 color 属性的值。

这是播放代码的链接。亲自尝试一下 - 在文本字段中输入颜色,看看会发生什么。

这是 propertiesstate 如何相互关联的一个典型例子。父组件的状态通常是通过 props 传递给其所有子组件的数据源。

在我们的例子中,存储在 bgColor state 属性中的 state 值变成了一个 color prop。

这个例子表明 stateprops 只是存储数据和管理数据流的两种方式。

在 React 中何时使用 stateprops

这不是一个或另一个的选择 - 组件维护状态并接收 props 是很常见的。存储在状态中的数据块往往成为子组件的 props。props 不限于数据 - 它们还可以包括回调函数。

要构建易于管理的 React 应用程序,请使用组件树中较高组件的状态。所有其他组件都应该是无状态的,并通过 props 接收必要的数据。无状态组件是首选,因为它们更易于阅读和测试。

综上所述,stateprops 都是必要的,如果没有 state,props 不会那么有效。通常,最好使用有状态组件进行事件处理和数据处理,而无状态组件更适合可视化和格式化。

Irakli Tchigladze avatar Irakli Tchigladze avatar

Irakli is a writer who loves computers and helping people solve their technical problems. He lives in Georgia and enjoys spending time with animals.

LinkedIn