将道具传递给从对象动态渲染的组件
Passing props to components rendered dynamically from object
我有一个充满组件的对象:
const Icons = {
// commonly used darksky icon names
"clear-day": <ClearDayIcon />,
"clear-night": <ClearNightIcon />,
"rain": <RainMediumIcon />,
"snow": <SnowIcon />,
"sleet": <RainHeavyIcon />,
"wind": <WindyDayIcon />,
// etc..
}
每个组件实际上只是一个包装为 React 组件的 svg。但是我需要它从它调用的地方接收道具,尤其是 className
道具。
我想要做的是以下列方式从我的其他组件调用这些组件:
<WeatherIcon icon={icon} className="some-class" />
图标属性将决定选择哪个图标组件。所以我尝试了这个:
const WeatherIcon = props => Icons[ props.icon ]
所以这部分工作,因为我可以写 <WeatherIcon icon={'clear-night'} />
,并且呈现了正确的组件。但是,无法将我的 WeatherIcon
组件中的任何其他道具向下传递到每个 Icon
。例如,写 <WeatherIcon icon={'clear-night'} className="some-class" />
显然不会将 className
属性(或任何其他属性)向下传递到每个单独的组件。我试过这样做:
const Icons = {
"clear-day": props => <ClearDayIcon {...props} />,
"clear-night": props => <ClearNightIcon {...props} />,
// etc..
}
但这不起作用,因为现在我返回的是 Component
而不是 <Component />
。我在问题Passing props to dynamically loaded components中看到了解决方案,但是这些都建议像{ Icons['clear-day'](className: 'some-class', anotherProp: 'some-prop') }
一样调用组件。我觉得这不是很优雅。必须有一种方法可以将其写成 <WeatherIcon icon={'some-icon'} className={'some-class'} someProp={'some-prop'} />
,并让 props 正确过滤。 (我确实意识到所有的道具都会一直过滤到我的 SVG 组件——这很好)。我觉得这里有一个更高阶的组件等待编写,但现在它在躲避我。
感谢阅读
我不是 100% 确定这是否会满足您的要求,但我可能会尝试这样的事情;
const Icons = {
"clear-day": ClearDayIcon,
"clear-night": ClearNightIcon,
"rain": RainMediumIcon,
"snow": SnowIcon,
"sleet": RainHeavyIcon,
"wind": WindyDayIcon,
// etc..
}
const Icon = ({icon, ...rest}) => {
const IconComponent = Icons[icon]
if(!IconComponent) {
// Or throw an exception maybe.
// At least print some console warnings in development env.
return null;
}
return <IconComponent {...rest} />
}
通过这种方式,您可以 select 您的一个图标组件并将任何道具传递给它。
而当你想使用它的时候,你可以这样使用它;
// ...
<Icon icon="clear-day" className="some-class" />
// ...
我发现这也行得通 - 编写包含组件的对象作为 props 的函数,returns 对象。然后你可以在每个组件中使用一个{...props}
:
const Icons = props => ({
"clear-day": <ClearDayIcon {...props} />,
"clear-night": <ClearNightIcon {...props} />,
"rain": <RainMediumIcon {...props} />,
etc.
})
然后包装器组件如下所示:
const WeatherIcon = props => Icons(props)[ props.icon ]
很简单 - 我知道我很接近。我不确定这是否被视为高阶组件 (HOC)。它 是 一个组件,returns 另一个基于它的 props 的组件,附加了新的 props。这算作 HOC 吗?
我有一个充满组件的对象:
const Icons = {
// commonly used darksky icon names
"clear-day": <ClearDayIcon />,
"clear-night": <ClearNightIcon />,
"rain": <RainMediumIcon />,
"snow": <SnowIcon />,
"sleet": <RainHeavyIcon />,
"wind": <WindyDayIcon />,
// etc..
}
每个组件实际上只是一个包装为 React 组件的 svg。但是我需要它从它调用的地方接收道具,尤其是 className
道具。
我想要做的是以下列方式从我的其他组件调用这些组件:
<WeatherIcon icon={icon} className="some-class" />
图标属性将决定选择哪个图标组件。所以我尝试了这个:
const WeatherIcon = props => Icons[ props.icon ]
所以这部分工作,因为我可以写 <WeatherIcon icon={'clear-night'} />
,并且呈现了正确的组件。但是,无法将我的 WeatherIcon
组件中的任何其他道具向下传递到每个 Icon
。例如,写 <WeatherIcon icon={'clear-night'} className="some-class" />
显然不会将 className
属性(或任何其他属性)向下传递到每个单独的组件。我试过这样做:
const Icons = {
"clear-day": props => <ClearDayIcon {...props} />,
"clear-night": props => <ClearNightIcon {...props} />,
// etc..
}
但这不起作用,因为现在我返回的是 Component
而不是 <Component />
。我在问题Passing props to dynamically loaded components中看到了解决方案,但是这些都建议像{ Icons['clear-day'](className: 'some-class', anotherProp: 'some-prop') }
一样调用组件。我觉得这不是很优雅。必须有一种方法可以将其写成 <WeatherIcon icon={'some-icon'} className={'some-class'} someProp={'some-prop'} />
,并让 props 正确过滤。 (我确实意识到所有的道具都会一直过滤到我的 SVG 组件——这很好)。我觉得这里有一个更高阶的组件等待编写,但现在它在躲避我。
感谢阅读
我不是 100% 确定这是否会满足您的要求,但我可能会尝试这样的事情;
const Icons = {
"clear-day": ClearDayIcon,
"clear-night": ClearNightIcon,
"rain": RainMediumIcon,
"snow": SnowIcon,
"sleet": RainHeavyIcon,
"wind": WindyDayIcon,
// etc..
}
const Icon = ({icon, ...rest}) => {
const IconComponent = Icons[icon]
if(!IconComponent) {
// Or throw an exception maybe.
// At least print some console warnings in development env.
return null;
}
return <IconComponent {...rest} />
}
通过这种方式,您可以 select 您的一个图标组件并将任何道具传递给它。 而当你想使用它的时候,你可以这样使用它;
// ...
<Icon icon="clear-day" className="some-class" />
// ...
我发现这也行得通 - 编写包含组件的对象作为 props 的函数,returns 对象。然后你可以在每个组件中使用一个{...props}
:
const Icons = props => ({
"clear-day": <ClearDayIcon {...props} />,
"clear-night": <ClearNightIcon {...props} />,
"rain": <RainMediumIcon {...props} />,
etc.
})
然后包装器组件如下所示:
const WeatherIcon = props => Icons(props)[ props.icon ]
很简单 - 我知道我很接近。我不确定这是否被视为高阶组件 (HOC)。它 是 一个组件,returns 另一个基于它的 props 的组件,附加了新的 props。这算作 HOC 吗?