【问题标题】:How can I display React component based on prop name passed into a container?如何根据传入容器的道具名称显示 React 组件?
【发布时间】:2017-02-01 23:11:52
【问题描述】:

UPDATE 解决得不好

const curSlide = this.props.name;

        const setView = () => {
            if(curSlide === 'Slide1') {
                return <Slide1 />
            } else if(curSlide === 'Slide2') {
                return <Slide2 />
            } else {
                return <Slide3 />
            }
        }

        return(
            <div>
                <center>
                    {setView()}
                </center>
            </div>

我有一个故事,其中包含一个承载不同组件的幻灯片容器。我的故事容器下有一个按钮,按下时会将 this.props.name + 1 传递给幻灯片容器。我希望幻灯片容器能够使用此信息并根据按钮单击呈现出正确的幻灯片。

我不确定为什么单击按钮时没有显示任何内容。

Story.js

import React, { Component, PropTypes } from 'react'
import sass from '../scss/application.scss'
import SlideContainer from './SlideContainer'


class Story extends Component {
    constructor(props){
        super(props)
            this.state = {
                name: '',
                count: 0
            }
    }   

    handleClick(e) {
        e.preventDefault();
        let tempCount = this.state.count + 1;
        let curSlide = `Slide${tempCount}`;

        this.setState({
            name: curSlide,
            count: tempCount
        });

    }

    render() {
        return(
            <div>
                <div>
                    <SlideContainer name={this.state.name}/>
                </div>
                <center><button className="btn btn-danger" onClick={this.handleClick.bind(this)}>
                        <span className="glyphicon glyphicon-heart"></span></button>
                </center>
            </div>
        )
    }
}


Story.propTypes = {
    name: PropTypes.string,
    count: PropTypes.number
}

export default Story;

SlideContainer.js

import React, { Component, PropTypes } from 'react'
import sass from '../scss/application.scss'
import Slide1 from './Slide1'
import Slide2 from './Slide2'


class SlideContainer extends Component {
    constructor(props){
        super(props)
            this.state = {
                name: ''
            }
    }   

    render() {

        let curSlide = this.props.name;

        return(
            <div>
                <center>
                    <curSlide />
                </center>
            </div>
        )
    }
}

SlideContainer.propTypes = {
    name: PropTypes.string
}

export default SlideContainer;

【问题讨论】:

  • 几个 OT cmets -
    我认为自 90 年代以来已被弃用。 Story.propTypes 也没有意义......故事有状态。
  • center 仍然可以正常工作,我应该将文本添加到 div 还是现在如何将 div 居中?
  • 通常所有样式都应该通过 CSS 完成 - 理论上浏览器可能会在某个时候开始放弃对
    的支持。

标签: reactjs button components


【解决方案1】:

您需要以某种方式将组件的名称映射到实际的组件实例。您可能可以通过执行以下操作使其工作:

import Slide1 from './Slide1'
import Slide2 from './Slide2'

class SlideContainer extends Component {
    constructor(props){
        super(props)
        this.state = {
            slideMapping = {
                'Slide1': Slide1,
                'Slide2': Slide2,
            };
        }
    }  


    render() {

        let curSlide = this.state.slideMapping[this.props.name];

        return(
            <div>
                <center>
                    <curSlide />
                </center>
            </div>
        )
    }
}

如果单个幻灯片组件的名称与道具中的幻灯片名称完全匹配,您可以像这样简单地创建映射:

this.state = {
    slideMapping: { Slide1, Slide2 }
}

它是否比您当前的修复更优雅,取决于您。

更新: 如果您想从SlideContainer 中分离出映射,您可以使用以下内容创建一个名为Slides.js 的新文件:

import Slide1 from './Slide1';
import Slide2 from './Slide2';

export const mapping = { Slide1, Slide2 };

在你的SlideComponent 中你会这样做:

import { mapping } from './Slides';

...

let curSlide = mapping[this.props.name];

【讨论】:

  • 我喜欢这个 - 我试试
【解决方案2】:

表达式&lt;curSlide/&gt; 刚刚编译为React.createElement(并且可能在运行时失败)。没有任何东西可以将组件的名称与您导入的两个模块中的任何一个联系起来。

也许将子组件作为道具传入:

const {Slide} = this.props // an actual React component... not a string
return (<div><Slide/></div>) 

其实,为什么不直接使用儿童呢?

// Story.js
const Slide = ... // figure out which component you want to display

<SlideContainer><Slide/></SlideContainer>

// SlideContainer.js
<div>{this.props.children}</div>

【讨论】:

  • 无法让 const {Slide} = this.props.name 不抛出错误。我通过为 this.props.name 设置一个 const 并返回一个函数来解决这个问题,该函数包含一系列试图匹配幻灯片的 if else 语句。它不漂亮,但它有效。不过,我正在寻求更好的解决方案。
  • 我认为你没有抓住重点。我认为您不应该尝试传递组件的“名称”。只需传递要渲染的子组件...理想情况下使用子组件(上面已编辑)
  • 谢谢。我能够解决我的阅读问题。但我做了 const Slide = this.props.module (w/o {}),并通过了
    }
猜你喜欢
  • 1970-01-01
  • 2015-01-03
  • 1970-01-01
  • 2020-10-09
  • 2015-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多