【问题标题】:How are boolean props used in React?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;


我的问题是:

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

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

  3. 如果 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 规范进行比较。

标签: reactjs boolean jsx react-props


【解决方案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 规范进行比较。


    答案:

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

    在 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 链接。

    在 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

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

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

    1. 此外,如果可以接受 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
    }
    
    

    所以总结和回答你的问题

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

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

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

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

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

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

    【讨论】:

    • 谢谢,但我仍然不明白这如何回答我的问题。
    • 在我的回答中添加了摘要。它会回答你的问题
    猜你喜欢
    • 1970-01-01
    • 2012-03-01
    • 2014-07-12
    • 2014-05-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-18
    • 1970-01-01
    相关资源
    最近更新 更多