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:
- 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.
- 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.
- 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.