Javascript 如何只将道具传递给React元素数组中的第一个元素?
如何将道具仅传递给未知元素数组中的第一个元素?例如,在下面的代码段中,Javascript 如何只将道具传递给React元素数组中的第一个元素?,javascript,reactjs,Javascript,Reactjs,如何将道具仅传递给未知元素数组中的第一个元素?例如,在下面的代码段中,元素是一个最多由3个自定义条元素组成的数组,我只希望第一个元素被传递一个任意属性 function Foo(props) { const myProp = 'test'; const elements = [ (isP && <Bar prop1={'p'} />), (isQ && <Bar prop1={'q'} />), (isR &
元素
是一个最多由3个自定义条
元素组成的数组,我只希望第一个元素被传递一个任意属性
function Foo(props) {
const myProp = 'test';
const elements = [
(isP && <Bar prop1={'p'} />),
(isQ && <Bar prop1={'q'} />),
(isR && <Bar prop1={'r'} />),
].filter(x => x);
// Now do something like 'elements[0].props.myProp = myProp'
return elements;
}
理想情况下,解决方案将高效、简洁地实现目标。如果没有比(1)或(2)更好的解决方案,我也会接受这个答案
编辑:我忘了澄清一些要点
- 我正在使用Redux,以防考虑到这一点
的实例实际上是多种类型的(例如,
,条码
,Bas
),以防严重影响答案。(我错误地把原来的问题简单化了。)Baz
- 我想我应该保持它的简单,并使用
推送:
function Foo(props) {
const myProp = 'test';
const elements = [];
if (isP) {
elements.push(<Bar myProp={myProp}/>);
}
if (isQ) {
elements.push(elements.length ? <Bar/> : <Bar myProp={myProp}/>);
}
if (isR) {
elements.push(elements.length ? <Bar/> : <Bar myProp={myProp}/>);
}
return elements;
}
如果falsy不正常,但未定义
为:
// ...
if (isQ) {
elements.push(<Bar myProp={elements.length ? undefined : myProp}/>);
}
// ...
(同样,根据myProp
的规则,可能会避免使用条件运算符)
等。如图所示,理想情况下,应通过调用减缩器中的函数来预计算源数据,以使数组具有正确的长度,并在需要时设置道具。这将意味着组件内部不必要的计算,在任何组件更新时都必须进行渲染
myArr: [
{ id: 0, someProp: { msg: 'hello' } },
{ id: 1: someProp: {} },
{ id: 2: someProp: {} }
]
或
然后组件只需执行以下操作
const Foo = (props) => {
const { myArr } = props;
return (
<div>
{
myArr.map(item => (
<Bar key={item.id} {...item.someProp} />
))
}
</div>
);
};
现在呢
import { COMPONENT_TYPE: { BAR, BAS, BAZ } } from '../common';
myArr: [
{ id: 0, someProp: { msg: 'hello' }, componentType: BAR },
{ id: 1: someProp: {}, componentType: BAS },
{ id: 2: someProp: {}, componentType: BAZ }
]
现在在我们的组件中
import { COMPONENT_TYPE: { BAR, BAS, BAZ } } from '../common';
const Foo = (props) => {
const { myArr } = props;
return (
<div>
{
myArr.map(item => (
<div key={item.id}>
{
item.componentType === BAR &&
<Bar {...item.someProp} />
}
{
item.componentType === BAS &&
<Bas {...item.someProp} />
}
{
item.componentType === BAZ &&
<Baz {...item.someProp} />
}
</div>
))
}
</div>
);
};
在映射中
只要枚举从大写改为实际的组件名称我就忍不住认为这是一个错误。如果您向我们展示实际的代码,我们可能会更有效地帮助您
不管怎样,如果我们在黑暗中刺伤,这里有另一种方法,你可以使用解构任务。如果isP
和isQ
和isR
都为false,将返回一个空数组
const Foo = (props) =>
{ const specs =
[ [ isP, 'p' ]
, [ isQ, 'q' ]
, [ isR, 'r' ]
]
const [ first, ...rest ] =
specs.reduce
( (acc, [ flag, prop ]) =>
flag ? [ ...acc, prop ] : acc
, []
)
if (first === undefined)
return []
return (
[ <Bar myProp={myProp} prop={first} />
, ...rest.map (prop => <Bar prop={prop} />)
]
)
}
constfoo=(道具)=>
{常数规格=
[[isP,'p']
,[isQ,'q']
,[isR,'r']
]
常数[第一,…剩余]=
规格减少
((acc,[标志,道具])=>
标志?[…acc,prop]:acc
, []
)
如果(第一个===未定义)
返回[]
返回(
[
,…rest.map(prop=>)
]
)
}
您说过,组件和道具可以根据不同的条件而有所不同。在这种情况下,您可以修改程序以支持您的独特需求-
const Foo = (props) =>
{ const specs =
[ [ isP, Bar, { prop: 'r' } ]
, [ isQ, Qux, { prop: 'q', another: 'a' } ]
, [ isR, Rox, { prop: 'r' } ]
]
return specs
.filter
( ([ flag, _0, _1 ]) => flag
)
.map
( ([ _, Comp, props ], i) =>
i === 0
? <Comp {...props} myProp={myProp} />
: <Comp {...props} />
)
}
constfoo=(道具)=>
{常数规格=
[[isP,Bar,{prop:'r'}]
,[isQ,Qux,{prop'q',另一个'a'}]
,[isR,Rox,{prop:'r'}]
]
退货规格
.过滤器
(([flag,_0,_1])=>flag
)
.地图
(([[uu,Comp,props],i)=>
i==0
?
:
)
}
您只想创建一个
?否,0-3个条形元素,具体取决于isP、isQ和isR的值。在(最多)3个条形元素中,只有第一个元素应该具有myProp
?是的,没错。isP
的值是多少。?布尔值<代码>未定义
还是真实?如果myProp
在您不想要它的时候是错误的,这可以吗?诀窍是您事先不知道将包含这三个选项中的哪一个,因此您不能依赖i==0
。这种条件逻辑在理想情况下不应该存在于组件中。它应该处于状态
或正在使用的任何存储中,并在其中订购,并在其中添加任何属性。组件应该只是呈现它,然后假设它是状态,只是为了问题的目的而简化。我的意思是说,在redux的上下文中,这个逻辑应该在reducer中确定,以便组件Foo
只接收数据,只需应用简单的布尔值,不执行循环和其他可能复杂的logic@tic你能在你的回答中解释一下你是如何重新构造代码以将条件逻辑移出的吗?听起来可能更好,但我想看看它的比较。我的代码只是对isP、isQ、isR有不同的值,每个实例实际上是一种不同类型的组件,应用了许多特定的道具。否则就一模一样了。@Cesarbautista我更新了答案。下次发布一个带有真实代码的问题。可以。我试图让每个人都不知道额外的细节,但不知道XY问题。谢谢你提出来!不用担心,我很乐意帮忙。我很高兴你的问题最终得到了解决。
const Foo = (props) => {
const { myArr } = props;
return (
<div>
{
myArr.map(item => (
<Bar key={item.id} {...item.someProp} />
))
}
</div>
);
};
export const COMPONENT_TYPE = {
BAR: 'BAR',
BAS: 'BAS',
BAZ: 'BAZ'
};
import { COMPONENT_TYPE: { BAR, BAS, BAZ } } from '../common';
myArr: [
{ id: 0, someProp: { msg: 'hello' }, componentType: BAR },
{ id: 1: someProp: {}, componentType: BAS },
{ id: 2: someProp: {}, componentType: BAZ }
]
import { COMPONENT_TYPE: { BAR, BAS, BAZ } } from '../common';
const Foo = (props) => {
const { myArr } = props;
return (
<div>
{
myArr.map(item => (
<div key={item.id}>
{
item.componentType === BAR &&
<Bar {...item.someProp} />
}
{
item.componentType === BAS &&
<Bas {...item.someProp} />
}
{
item.componentType === BAZ &&
<Baz {...item.someProp} />
}
</div>
))
}
</div>
);
};
const Component = item.componentType;
<Component {...item.someProp} />
const Foo = (props) =>
{ const specs =
[ [ isP, 'p' ]
, [ isQ, 'q' ]
, [ isR, 'r' ]
]
const [ first, ...rest ] =
specs.reduce
( (acc, [ flag, prop ]) =>
flag ? [ ...acc, prop ] : acc
, []
)
if (first === undefined)
return []
return (
[ <Bar myProp={myProp} prop={first} />
, ...rest.map (prop => <Bar prop={prop} />)
]
)
}
const Foo = (props) =>
{ const specs =
[ [ isP, Bar, { prop: 'r' } ]
, [ isQ, Qux, { prop: 'q', another: 'a' } ]
, [ isR, Rox, { prop: 'r' } ]
]
return specs
.filter
( ([ flag, _0, _1 ]) => flag
)
.map
( ([ _, Comp, props ], i) =>
i === 0
? <Comp {...props} myProp={myProp} />
: <Comp {...props} />
)
}