【问题标题】:Conditionally pass a Boolean prop with a dynamic prop name to a React component有条件地将具有动态道具名称的布尔道具传递给 React 组件
【发布时间】:2019-03-11 02:58:17
【问题描述】:

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

所以,我可能有类似<MyEvent isRecurring /> 的东西,它将isRecurring 属性传递为true,而<MyEvent /> 会将isRecurring 视为false(或未定义)。

当道具的名称是动态的(存储在变量中)时,是否可以传递没有值的道具(因此,它的存在意味着它是true)?

例如,这个不起作用

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

用例

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

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

感觉就像为我认为微不足道的事情多写了 2 行代码。

或者有没有类似于我上面写的方法?

【问题讨论】:

  • 为什么您认为您的解决方案还不理想?
  • 也许你可以写一些适配器。实际上,你为什么需要它?
  • @Leu @Alex - 你们两个都有道理。我可以轻松地将我的道具明确设置为 true 并完成它。但是,我希望利用 JSX 如何获取一个没有值的 prop 名称并将其默认为 true,以便动态地输入一些 prop 名称,而不需要给它们值(例如 true)。

标签: reactjs jsx


【解决方案1】:

文档说:“一般来说,我们不建议使用它,因为它可能与 ES6 对象简写 {foo} 混淆,后者是 {foo: foo} 而不是 {foo: true} 的缩写. 这种行为就在那里,因此它与 HTML 的行为相匹配。” – 我确实理解了这个想法,但是你最好传递 true。

【讨论】:

  • 我在文档中也读到了同样的声明,所以我听到了你在说什么。但是,即使他们不推荐传递没有值的道具,语法规则也允许这样做;所以,我只是想知道这是否意味着也有一种方法可以对动态命名的道具执行此操作。
【解决方案2】:

看看这些例子:

// 示例(一)

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中显示props值

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    • 2018-07-17
    • 2019-04-24
    • 2018-12-17
    • 2018-08-01
    • 2015-11-20
    • 2018-10-05
    相关资源
    最近更新 更多