【问题标题】:Passing props to components rendered dynamically from object将道具传递给从对象动态呈现的组件
【发布时间】:2020-05-12 09:02:31
【问题描述】:

我有一个充满组件的对象:

const Icons = {
   // commonly used darksky icon names
   "clear-day": <ClearDayIcon />,
   "clear-night": <ClearNightIcon />,
   "rain": <RainMediumIcon />,
   "snow": <SnowIcon />,
   "sleet": <RainHeavyIcon />,
   "wind": <WindyDayIcon />,
   // etc..
}

每个组件实际上只是一个包装为反应组件的 svg。但我需要它从它调用的地方接收道具,尤其是className 道具。

我希望能够通过以下方式从我的其他组件中调用这些组件:

<WeatherIcon icon={icon} className="some-class" />

icon 属性将决定选择哪个图标组件。所以我尝试了这个:

const WeatherIcon = props => Icons[ props.icon ]

所以这部分工作,因为我可以写&lt;WeatherIcon icon={'clear-night'} /&gt;,并呈现正确的组件。但是,没有办法将我的WeatherIcon 组件中的任何其他道具向下传递到每个Icon。例如,写&lt;WeatherIcon icon={'clear-night'} className="some-class" /&gt; 显然不会将className 道具(或任何其他道具)传递到每个单独的组件。我试着做这样的事情:

const Icons = {
   "clear-day": props => <ClearDayIcon {...props} />,
   "clear-night": props => <ClearNightIcon {...props} />,
   // etc..
}

但这不起作用,因为现在我返回的是 Component 而不是 &lt;Component /&gt;。我在问题Passing props to dynamically loaded components 中看到了解决方案,但是这些都建议调用像{ Icons['clear-day'](className: 'some-class', anotherProp: 'some-prop') } 这样的组件。我觉得这不是很优雅。必须有办法将其写为&lt;WeatherIcon icon={'some-icon'} className={'some-class'} someProp={'some-prop'} /&gt;,并正确过滤道具。 (我确实意识到所有的道具都会一直过滤到我的 SVG 组件——这很好)。我觉得这里有一个更高阶的组件等着写,但现在它在躲避我。

感谢阅读

【问题讨论】:

    标签: javascript reactjs react-props higher-order-components


    【解决方案1】:

    我不能 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} />
    }
    
    

    通过这种方式,您可以选择一个 Icon 组件并将任何道具传递给它。 而当你想使用它的时候,你可以这样使用它;

    // ...
    <Icon icon="clear-day" className="some-class" />
    // ...
    

    【讨论】:

      【解决方案2】:

      我发现这也有效 - 将包含组件的对象编写为 props 的函数,它返回对象。然后你可以在每个组件中使用{...props}

      const Icons = props => ({
         "clear-day": <ClearDayIcon {...props} />,
         "clear-night": <ClearNightIcon {...props} />,
         "rain": <RainMediumIcon {...props} />,
         etc.
      })
      

      那么包装器组件是这样的:

      const WeatherIcon = props => Icons(props)[ props.icon ]
      

      很简单 - 我知道我很接近。我不确定这是否被认为是高阶组件(HOC)。它一个组件,它根据其 props 返回另一个组件,并附加新的 props。这算作 HOC 吗?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-01-17
        • 1970-01-01
        • 2021-07-08
        • 2019-01-27
        • 1970-01-01
        • 1970-01-01
        • 2019-05-17
        相关资源
        最近更新 更多