Reputation: 5182
I know that boolean props can be passed to a React component as true
or false
simply by their presence or absence (as per React JSX documentation and this answer by Artif3x in this StackOverflow question.
So, I might have something like <MyEvent isRecurring />
which passes the isRecurring
prop as true
, whereas <MyEvent />
would see isRecurring
as false
(or undefined).
Is it possible to pass a prop with no value (so, it's presence means it is true
) when the name of the prop is dynamic (stored in a variable)?
For example, this does not work:
const propToSetToTrue = someCondition ? 'isRecurring' : 'isArchived'
<MyEvent {propToSetToTrue} /> // Syntactically, not allowed
And, to use object spread, I need to set the prop equal to something (naturally, that would be true
). This does work, but it's not exactly what I am looking for:
// Assume props already populated at this point
const propToSetToTrue = someCondition ? 'isRecurring' : 'isArchived'
props[propToSetToTrue] = true // This works, but it's not ideal
<MyEvent {...props} />
I've gotten a few comments asking why I might need this. Here is a possible use case, in testing:
// sharedExamples/props.js
function textDependsOnProp(Component, propName, testId) {
it(`sets text to 'FOO' when prop '` + propName + `' is given'`, () => {
const { queryByTestId } = render(<Component {propName} />) // This does not work
expect(queryByTestId(testId).textContent).toEqual('FOO')
})
it(`sets text to 'BAR' when prop '` + propName + `' is not given'`, () => {
const { queryByTestId } = render(<Component />)
expect(queryByTestId(testId).textContent).toEqual('BAR')
})
}
My tests are in the process of being refactored to be used for many different components, and the actual prop name to focus on may be different for each component, which is why the prop name is dynamic.
So, should I just forget about what I thought was ideal and just explicitly set my prop to true, like so:
const props = {}
props[propName] = true
render(<Component {...props} />)
It just felt like 2 extra lines of code for something I thought could be trivial.
Or is there a way to do it similar to what I've written above?
Upvotes: 1
Views: 5530
Reputation: 1618
Check out these examples:
// Example (1)
props['isRecuring'] = true;
<MyEvent {...props}/> // => <MyEvent isRecuring={true}/>
// Example (2)
<MyEvent isRecuring/>
// Example (3)
props['isRecuring'] = undefined;
<MyEvent {...props}/> // => <MyEvent /> mean the isRecuring is not present
Try to display props value in MyEvent
const MyEvent = (props) => (
<div>props: {JSON.stringify(props)}</div>
)
The result of (1) example is {}
, while (2) & (3) display {"isRecuring": true}
Based on the above example, I can say that spreading will ignore the props with value of undefined
. Therefore, it not present and will never be passed as props to the component (MyEvent).
I think your solution is the only way to pass boolean props using spread. It the matter of spreading in JS, not the React at all.
Upvotes: 0
Reputation: 74
The documentation says: "In general, we don’t recommend using this because it can be confused with the ES6 object shorthand {foo} which is short for {foo: foo} rather than {foo: true}. This behavior is just there so that it matches the behavior of HTML." – I do dig the idea but, you're probably better off passing true.
Upvotes: 1