My App

属性与状态

属性与状态

在学习 React 时,“props”和“state”的概念有些混淆是很正常的。它们之间究竟有什么区别?什么时候使用 props,什么时候使用 state?

在本课中,我们的目标是澄清这个常见的混淆来源。

属性

“Props” 是 “properties” 的缩写。在微观层面上,它们就像我们在 HTML 元素上放置的属性,如 class 或 href :

<a
  class="nav-link"
  href="/category/stuff"
>

例如,下面的 Button 组件接受一个“variant”属性。这个属性将被内部使用来控制样式,类似于 HTML 中 class 属性的工作方式。

import Button from './Button';

function App() {
  return (
    <div className="box">
      <p>
        Are you sure you want to continue?
      </p>
      <div className="actions">
        <Button variant="secondary">
          Cancel
        </Button>
        <Button variant="primary">
          Confirm
        </Button>
      </div>
    </div>
  );
}

export default App;

Props 允许我们自定义给定组件的行为,以便在不同场景中相同的组件可以执行不同的操作。

Props 是我们组件的输入,就像传递给函数的参数。

状态

在上面的示例中,我们的应用程序是完全静态的。每次运行这些代码,我们都会得到相同的结果。直到宇宙的热寂,这种情况将一直保持。

但是如果我们想要一些东西随时间变化呢?这就是状态的作用。

让我们稍微调整一下我们的例子:

import React from 'react';

import Button from './Button';

function App() {
  const [hasAgreed, setHasAgreed] = React.useState(false);
  
  return (
    <div className="box">
      <p>
        Are you sure you want to continue?
      </p>
      <label htmlFor="confirm-checkbox">
        <span className="required">*</span>
        <input
          id="confirm-checkbox"
          type="checkbox"
          value={hasAgreed}
          onChange={() => setHasAgreed(!hasAgreed)}
        />
        <span>
          I agree with <a href="/terms">the terms</a>.
        </span>
      </label>
      <div className="actions">
        <Button
          variant="secondary"
          isEnabled={true}
        >
          Cancel
        </Button>
        <Button
          variant="primary"
          isEnabled={hasAgreed}
        >
          Confirm
        </Button>
      </div>
    </div>
  );
}

export default App;

我们有一个新的状态, hasAgreed ,我们需要使用这些数据来驱动我们的“确认”按钮。这揭示了关于 props 的一个重要真相:它们是允许数据在我们的应用程序中流动的通道。

让我们深入探讨这个想法。

想出正确的props名

我可以选择将我的 prop 命名为 disabled ,而不是编造一个 isEnabled prop,像这样:

// [!code highlight="1"]
function Button({ variant, disabled, children }) {
  return (
    <button
      className={`${styles.wrapper} ${styles[variant]}`}
      disabled={disabled}
    >
      {children}
    </button>
  );
}

实际上,这就是我在现实世界中可能会这样做的方式,但在这个例子中我选择了 isEnabled 来避免出现两个事物——我们的自定义属性和 HTML 属性——都叫做 disabled 的模糊性。

不要disable按钮

在这个例子中,我使用 disabled 属性禁用了一个按钮。结果表明,这个属性对可用性不好。

禁用的按钮不会向用户反馈问题所在。相反,我们应该始终允许按钮被点击;如果缺少某些内容或无效,我们可以引导用户找到问题。

有关更多信息,请查看亚当·西尔弗的这篇文章:“禁用按钮的问题及替代方法”。

On this page