在 React 中如何使用 boolean 属性?

How are boolean props used in React?

我试图澄清我对 React 中的布尔属性的一些困惑。

假设一个 MyComponent 有几个布尔属性 prop1, prop2...

首先:布尔属性似乎与其他属性一样:您可以在 defaultProps or in destructuring params:

中定义默认值
const MyComponent = ({ prop1, prop2 }) => (
   ...
);

MyComponent.defaultProps = {
  prop1: false,
  prop2: true,
}

或者(等同于...我认为)

const MyComponent = ({ prop1 = false, prop2 = true }) => (
 ...
) 

不清楚的是如何传递值。同样,自然的“React 风格”似乎是

  <MyComponent prop1={ BOOLEAN_EXPRESION1 } prop2={ BOOLEAN_EXPRESION2 } />

...包括 (false/true).

然而, that the correct (recommended?) way to pass boolean properties is presence/absence of the attribute, as in HTML5.

因此,应该写 <MyComponent prop1 />.

而不是 <MyComponent prop1={true} prop2={false} />

我的问题是:

  1. 传递布尔值的正确方式是什么?两者都可以接受吗?

  2. 如果 HTML5 风格是推荐的(或正确的)方式,如何处理动态值?

  3. 万一HTML5样式可以接受,那么默认值呢? 在上面的示例中(默认情况下 prop2true),如果我写 <MyComponent />prop2 会得到什么值?


已编辑:对于已接受的答案,我想添加我自己的提示:为了与 HTML5 风格一起玩,设计你的布尔道具他们 默认为 false。换句话说:默认为 true 的布尔属性应该被视为反模式。

取决于用例。听说过关注点分离吗?同样的原则也适用于此。在有意义的地方处理它。您可以在组件中使用变量而不是 defaultProps(React 方式)。如果它是一个开关,则将其从父级传递下来。

前注:

让我们换个角度思考,忽略 HTML5 建立的规则,只关注 JSX。 JSX 有恰好两种传递 true<MyComponent prop /><MyComponent prop={true} /> 的方法,恰好有一种传递 false [=16 的方法=].我同意这是区分 HTML5 和 JSX 的一个奇怪之处,但是 JSX 是 JavaScript 而不是 HTML 的语法扩展,所以它不会需要符合HTML.

的任意一条规则

来自JSX docs:

This funny tag syntax is neither a string nor HTML.

仅供参考,JSX 的所有规则和行为都列在 React 的 JSX docs, and it includes how defaulting a prop to true 作品中。 重要说明:这些文档不继承 HTML 的任何内容,也不应与 HTML 规范进行比较。


答案:

  1. What is the correct way of passing boolean props?

在 JSX 中传递显式 true

传递显式true有两种方法:传递truedefaulting a prop to true

<MyComponent prop={true} />
<MyComponent prop />

注意: 如文档中所述,JSX 将 prop 默认为 true 的行为只是与 HTML5's boolean attributes behavior 匹配的附加功能。

在 JSX 中传递显式 false

只有一种方法可以显式传递 false:传递 false

<MyComponent prop={false} />

注意: 这是 JSX 的行为不同于 HTML5 的布尔属性行为的地方。在 JSX 中没有默认为 false 这样的东西;它仅适用于传递显式 true。与 HTML5 相反,如果您不传递任何内容,那么您实际上传递的是 undefined,并且将使用您定义的默认值。这与 HTML5 规格相反,后者会说它是 false。有关此行为,请参阅 #3 的答案中的 CodeSandbox link。

在 JSX 中传递布尔值 variable/expression:

将变量或表达式传递给 prop:

// via variable
const foo = true;
<MyComponent prop={foo} />
const bar = false;
<MyComponent prop={bar} />

// via expression
<MyComponent prop={Math.random() > 0.5} />

Are both acceptable?

关于传递显式 true 与默认属性 true 的方式,它们在编译 JSX 方面都是可以接受的。但是,如果您需要代码库的一致性以遵守某种风格,请添加 ESLint 规则 jsx-boolean-value。我个人使用 Airbnb JavaScript 样式来启用该规则。该指南强调可读性,因此决定省略显式 true.

  1. In case HTML5 style is the recommended (or correct) way , how would one deal with dynamic values?

不要对动态值使用 HTML5 样式(默认属性为 true)(variables/expressions);使用 React 传递道具的方式(显式分配道具值)。请参阅上文了解如何通过这些。

  1. Furthermore, in case HTML5 style is acceptable, what about the default values? In the example above (where prop1,prop2 are resp. false/true by default) what would give?

这里是 prop1prop2 分别通过的最终值:

MyComponent.defaultProps = {
  prop1: false,
  prop2: true,
}

<MyComponent prop1 />
// prop1 == true
// prop2 == true // defaulted to true

<MyComponent prop1={true} prop2={false} />
<MyComponent prop1 prop2={false} />
// prop1 == true
// prop2 == false

这是 CodeSandbox link:https://codesandbox.io/s/elated-davinci-izut1?fontsize=14&hidenavigation=1&theme=dark

注:不加属性再不传值(如第一个例子中的prop2)等同于传undefined与第二个示例传递显式 false 不同。因此,prop2 被默认为 true

让我告诉你传递布尔值

HTML5风格

<MyComponent
  prop2  // equivalent prop2={true}, works only for static true values
  prop1={false} // You can't do something like that for false though
/>

// example
<Select
  multiSelect // You won't be changing this value throughout the whole life cycle
/>

// They will however transpiled to 
React.createElement(MyComponent, {prop1: false, props2: true}, null)
// So passing true isn't necessarily a must

默认道具

此方法对于布尔值与其他类型没有任何不同

<MyComponent
  title={title} // typeof title = string | undefined | null
  bold={bold} // typeof bold = boolean | undefined | null
/>

// In case title being undefined or null,
// React will take the defaultProps

defaultProps等同于

static defaultProps = {
  title: 'Hello World',
  bold: true
}

props = {
  title: props.title ?? 'Hello World',
  bold: props.bold ?? true
}


// Or in function, it's much simpler and familiar
// Same as old C, if the props are undefined or null,
// default values will be taken, this is plain 'ol JS
const MyComponent = ({title = 'Hello World', bold = true}) => {
  // boop
}


所以总结并回答你的问题

  1. 传递布尔值的正确方式是什么?两者都可以接受吗?

是的,两者都可以接受。 React 是不拘一格的,这取决于您遵循的是哪种风格,AirBnB 建议您使用 HTML5 风格来传递静态 true 值,而旧的 TypeScript 会尖叫着您将其更改为 props2={true}.

  1. 万一 HTML5 风格是推荐的(或正确的)方式,如何处理动态值?

HTML5 仅适用于静态 true 值。您根本无法在 HTML5 样式中使用动态布尔值。

  1. 此外,如果HTML5样式可以接受,那么默认值呢?在上面的示例中(默认情况下 prop2 为真),如果我写 <MyComponent />,会发生什么?

<MyComponent /> 将被转译为 React.createElement(MyComponent, {}, null),这意味着 prop1prop2 将是 undefined。鉴于 prop1 的默认值是 falseprop2true。将采用它们各自的默认值。