React 中如何使用布尔属性?
Posted
技术标签:
【中文标题】React 中如何使用布尔属性?【英文标题】:How are boolean props used in React? 【发布时间】:2020-07-04 02:28:56 【问题描述】:我试图澄清我对 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 />
...包括static literals (false/true
)。
但是,it's also stated 认为传递布尔属性的正确(推荐?)方法是属性的存在/不存在,如 in html5。
因此,应该写<MyComponent prop1 />
,而不是<MyComponent prop1=true prop2=false />
。
我的问题是:
传递布尔道具的正确方法是什么?都可以接受吗?
如果 HTML5 样式是推荐(或正确)的方式,如何处理动态值?
如果 HTML5 样式可以接受,那么默认值呢?
在上面的例子中(prop2
默认为true
),如果我写<MyComponent />
,prop2
会得到什么值?
已编辑:对于已接受的答案,我想添加我自己的提示:要与 HTML5 风格完美搭配,请设计您的布尔道具,以便它们 默认为 @ 987654340@。换句话说:默认为 true
的布尔属性应该被视为反模式。
【问题讨论】:
查看 React 文档如何处理 boolean props 的复选框。我不会推荐 html5 样式,因为您的默认值仅在默认值为 false 时才有效。 JSX 不是 html5 @HMR 这是我的印象,但在任何文档和 eslinter 中似乎都没有气馁,并且链接的答案有 42 个赞成... 这里要记住一点,OP:JSX不是html5 @leonbloy,好吧,让我们换个角度思考,忽略 HTML5 建立的规则,只关注 JSX。 JSX 有正好有两种传递 true 的方式,<MyComponent prop />
和 <MyComponent prop=true />
和 正好有一种传递 false 的方式<MyComponent prop=false />
。我同意这是区分 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 的方式,<MyComponent prop />
和 <MyComponent prop=true />
和 正是一种传递 false 的方式<MyComponent prop=false />
。我同意这是区分 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)会给出什么?
以下是分别传递的prop1
和prop2
的最终值:
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),如果我写
<MyComponent />
,会发生什么?
<MyComponent />
将被转换为React.createElement(MyComponent, , null)
,这意味着prop1
和prop2
将是undefined
。假设prop1
的默认值是false
而prop2
是true
。将采用它们各自的默认值。
【讨论】:
谢谢,但我仍然不明白这如何回答我的问题。 在我的回答中添加了摘要。它会回答你的问题以上是关于React 中如何使用布尔属性?的主要内容,如果未能解决你的问题,请参考以下文章