How are boolean props used in React?

一笑奈何 提交于 2020-12-13 04:51:54

问题


I'm trying to clarify some confusion (preferably from authoritative sources) about boolean props in React.

Suppose a have MyComponent with several boolean props prop1, prop2...

First: it would seem that boolean props are like just others: you can define default values, either in defaultProps or in destructuring params:

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

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

Or equivalently (no?)

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

What's not clear is how to pass values. The natural "React style", again, seems to be

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

... including the static literals (false/true).

However, it's also stated that the correct (recommended?) way to pass boolean properties is presence/absence of the attribute, as HTML5 dictates.

So that, instead of <MyComponent prop1={true} prop2={false} />, one should write <MyComponent prop1 />.


My questions are:

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

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

  3. Furthermore, in case HTML5 style is acceptable, what about the default values? In the example above (where prop2 is true by default), if I write <MyComponent />, what would happen?


回答1:


Forenote:

Let's just think this differently and disregard rules established by HTML5 and focusing only on JSX. JSX has exactly two ways of passing true, <MyComponent prop /> and <MyComponent prop={true} /> and exactly one way of passing false <MyComponent prop={false} />. I do agree this is an oddity distinguishing between HTML5 and JSX, but JSX is a syntax extension to JavaScript and not HTML so it does not need to conform to any of the rules of HTML.

From the JSX docs:

This funny tag syntax is neither a string nor HTML.

FYI, all rules and behavior of JSX is listed in React's JSX docs, and it includes how defaulting a prop to true works. Important note: these docs do not inherit anything from HTML and shouldn't be compared with HTML specs either.


Answers:

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

Passing an explicit true in JSX:

There are exactly two ways to pass an explicit true: passing true and defaulting a prop to true:

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

Note: As stated in the docs, JSX's behavior of defaulting a prop to true is just an added feature that matches with HTML5's boolean attributes behavior.

Passing an explicit false in JSX:

There is exactly one way to pass an explicit false: passing false

<MyComponent prop={false} />

Note: This is where JSX's behavior differ from HTML5's boolean attributes behavior. There is not such thing as defaulting to false in JSX; it is only applicable for passing an explicit true. In contrast to HTML5, if you do not pass anything, you're really passing undefined, and your defined default values will be used instead. This is contrary to the HTML5 specs which would say it's false. Refer to the CodeSandbox link in the answer to #3 for this behavior.

Passing a boolean variable/expression in JSX:

Pass the variable or an expression to the 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?

Referring to the way of passing an explicit true vs defaulting a prop to true, they are both acceptable in terms of compiling JSX. However, if you need consistency in a codebase for adhering to a certain style, add the ESLint rule jsx-boolean-value. I personally use the Airbnb JavaScript style which turns that rule on. The guide emphasizes on readability, and so it decided for omitting the explicit true.

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

Do not use HTML5 style (defaulting props to true) for dynamic values (variables/expressions); use the React way of passing props (explicitly assigning prop values). See above for how to pass those.

  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?

Here are the final values for prop1 and prop2 passed respectively:

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

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

Note: Not adding an attribute and then not passing a value (such as prop2 in the first example) is the same as passing undefined unlike passing an explicit false for the second example. Therefore, prop2 got defaulted to true.




回答2:


Let me tell you about passing boolean values

HTML5 Style

<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

Default Props

This method isn't any different for boolean than other types

<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 are equivalent to

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
}


So to summarize and answer your question

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

Yes, both are acceptable. React is un-opinionated, It depends upon which style you're following, AirBnB recommends you to use HTML5 style for passing static true values, while old TypeScript screams at you to change it to props2={true}.

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

HTML5 is applicable only for static true values. There's simply no way for you to use dynamic boolean values in HTML5 style.

  1. Furthermore, in case HTML5 style is acceptable, what about the default values? In the example above (where prop2 is true by default), if I write <MyComponent />, what would happen?

<MyComponent /> will be transpiled to React.createElement(MyComponent, {}, null), meaning prop1 and prop2 will be undefined. Given that the default values for prop1 is false while prop2 is true. Their respective default values will be taken.




回答3:


Depends on use case. Ever heard of separation of concerns? The same principle apply here. Handle it where it makes sense to handle. You can use variables in a component instead of defaultProps (the React way). If its a switch pass it down from parent.



来源:https://stackoverflow.com/questions/60816731/how-are-boolean-props-used-in-react

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!