有条件地将具有动态属性名称的布尔属性传递给React组件

时间:2019-03-11 02:58:18

标签: reactjs jsx

我知道布尔属性可以通过truefalse的存在或不存在(按照React JSX documentationthis answer by Artif3x in this StackOverflow question的形式传递给React组件)。

因此,我可能会遇到类似<MyEvent isRecurring />的事物,它将isRecurring道具传递为true,而<MyEvent />会将isRecurring视为false (或未定义)。

当道具名称是动态的(存储在变量中)时,是否可以传递不带值的道具(所以,它的存在意味着它是true)? < / p>

例如,此不起作用

const propToSetToTrue = someCondition ? 'isRecurring' : 'isArchived'

<MyEvent {propToSetToTrue} />  // Syntactically, not allowed

并且,要使用对象传播,我需要将prop设置为等于某个值(自然地,该值为true)。 确实可行,但这并不是我想要的:

// Assume props already populated at this point
const propToSetToTrue = someCondition ? 'isRecurring' : 'isArchived'
props[propToSetToTrue] = true // This works, but it's not ideal
<MyEvent {...props} />

用例

我收到了一些评论,询问为什么我可能需要这个。在测试中,这是一个可能的用例:

// 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')
  })
}

我的测试正在重构以用于许多不同的组件,并且每个组件要关注的实际道具名称可能有所不同,这就是道具名称具有动态性的原因。

所以,我应该忘记我的想法是什么,只是将我的属性设置为true,就像这样:

const props = {}
props[propName] = true
render(<Component {...props} />)

对于我认为微不足道的东西来说,感觉像是多了两行代码。

或者有没有办法像我上面写的那样?

1 个答案:

答案 0 :(得分:0)

查看以下示例:

//示例(1)

props['isRecuring'] = true;
<MyEvent {...props}/> // => <MyEvent isRecuring={true}/>

//示例(2)

<MyEvent isRecuring/>

//示例(3)

props['isRecuring'] = undefined;
<MyEvent {...props}/> // => <MyEvent /> mean the isRecuring is not present

尝试在MyEvent中显示道具值

const MyEvent = (props) => (
   <div>props: {JSON.stringify(props)}</div>
)

(1)示例的结果为{},而(2)&(3)显示{"isRecuring": true}

基于以上示例,我可以说传播将忽略值为undefined的道具。因此,它不存在,也永远不会作为道具传递给组件(MyEvent)。

我认为您的解决方案是使用传播传递布尔属性的唯一方法。这是在JS中传播的问题,根本不是React。