React 中如何使用布尔属性?

Posted

技术标签:

【中文标题】React 中如何使用布尔属性?【英文标题】:How are boolean props used in React? 【发布时间】:2020-07-04 02:28:56 【问题描述】:

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

假设有 MyComponent 和几个布尔属性 prop1prop2...

首先:布尔属性似乎和其他属性一样:您可以在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  />

...包括static literals (false/true)。

但是,it's also stated 认为传递布尔属性的正确(推荐?)方法是属性的存在/不存在,如 in html5。

因此,应该写&lt;MyComponent prop1 /&gt;,而不是&lt;MyComponent prop1=true prop2=false /&gt;


我的问题是:

    传递布尔道具的正确方法是什么?都可以接受吗?

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

    如果 HTML5 样式可以接受,那么默认值呢? 在上面的例子中(prop2默认为true),如果我写&lt;MyComponent /&gt;prop2会得到什么值?


已编辑:对于已接受的答案,我想添加我自己的提示:要与 HTML5 风格完美搭配,请设计您的布尔道具,以便它们 默认为 @ 987654340@。换句话说:默认为 true 的布尔属性应该被视为反模式。

【问题讨论】:

查看 React 文档如何处理 boolean props 的复选框。我不会推荐 html5 样式,因为您的默认值仅在默认值为 false 时才有效。 JSX 不是 html5 @HMR 这是我的印象,但在任何文档和 eslinter 中似乎都没有气馁,并且链接的答案有 42 个赞成... 这里要记住一点,OP:JSX不是html5 @leonbloy,好吧,让我们换个角度思考,忽略 HTML5 建立的规则,只关注 JSX。 JSX 有正好有两种传递 true 的方式&lt;MyComponent prop /&gt;&lt;MyComponent prop=true /&gt;正好有一种传递 false 的方式&lt;MyComponent prop=false /&gt;。我同意这是区分 HTML5 和 JSX 的奇怪之处,但是 JSX 是 javascript 的语法扩展,而不是 HTML,因此它不需要符合 HTML 的所有规则。 仅供参考,JSX 的所有规则和行为都列在 React 文档中,其中包括默认为 true 的工作方式 (reactjs.org/docs/jsx-in-depth.html#props-default-to-true)。这些文档没有从 HTML 继承任何东西,也不应该与 HTML 规范进行比较。 【参考方案1】:

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

【讨论】:

【参考方案2】:

前言:

让我们换个角度思考,忽略 HTML5 建立的规则,只关注 JSX。 JSX 有两种传递 true 的方式&lt;MyComponent prop /&gt;&lt;MyComponent prop=true /&gt;正是一种传递 false 的方式&lt;MyComponent prop=false /&gt;。我同意这是区分 HTML5 和 JSX 的奇怪之处,但 JSX 是 JavaScript 的语法扩展,而不是 HTML,因此它不需要遵守任何 HTML 规则。

来自JSX docs:

这个有趣的标签语法既不是字符串也不是 HTML。

仅供参考,JSX 的所有规则和行为都列在 React 的 JSX docs 中,其中包括 defaulting a prop to true 的工作原理。 重要提示:这些文档没有从 HTML 继承任何东西,也不应该与 HTML 规范进行比较。


答案:

    传递布尔道具的正确方法是什么?

在 JSX 中传递显式 true

传递明确的true 有两种方法:传递true 和defaulting 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 链接。

在 JSX 中传递布尔变量/表达式:

将变量或表达式传递给道具:

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

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

都可以接受吗?

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

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

不要对动态值(变量/表达式)使用 HTML5 样式(默认 props 为 true);使用 React 传递 props 的方式(显式分配 prop 值)。请参阅上文了解如何通过这些。

    此外,如果可以接受 HTML5 样式,那么默认值呢?在上面的示例中(prop1、prop2 默认分别为 false/true)会给出什么?

以下是分别传递的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 链接:https://codesandbox.io/s/elated-davinci-izut1?fontsize=14&hidenavigation=1&theme=dark

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

【讨论】:

谢谢。这仍然没有回答我的问题 3。 哦,忘了说prop2。对不起 @leonbloy,我忘了提到,在第一个示例中不定义属性,然后不定义值,就像在第一个示例中的 prop2 中那样,与在第二个示例中传递 undefined 不同,这与传递 false 相同。答案已更新:)【参考方案3】:

让我告诉你关于传递布尔值

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



所以总结和回答你的问题

    传递布尔道具的正确方法是什么?都可以接受吗?

是的,两者都可以接受。 React 是无主见的,这取决于你所遵循的风格,AirBnB 建议你使用 HTML5 风格来​​传递静态 true 值,而旧的 TypeScript 则要求你将其更改为 props2=true

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

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

    此外,如果 HTML5 样式可以接受,那么默认值呢?在上面的例子中(prop2默认为true),如果我写&lt;MyComponent /&gt;,会发生什么?

&lt;MyComponent /&gt; 将被转换为React.createElement(MyComponent, , null),这意味着prop1prop2 将是undefined。假设prop1 的默认值是falseprop2true。将采用它们各自的默认值。

【讨论】:

谢谢,但我仍然不明白这如何回答我的问题。 在我的回答中添加了摘要。它会回答你的问题

以上是关于React 中如何使用布尔属性?的主要内容,如果未能解决你的问题,请参考以下文章

如何根据条件语句添加 React 组件,基于可变计数器评估布尔值

如何使用 JavaScript 添加布尔属性

如何在labview中使用键盘控制 布尔开关

如何在目标 C 类中设置布尔类型属性

如何在反应中使用redux中的布尔状态值渲染组件?

在 JSX 中使用属性的布尔值