2017-02-01 1 views
1

UPDATE решаемые плохо сКак я могу отобразить компонент React на основе имени prop, переданного в контейнер?

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; 
+0

Несколько комментариев OT -

было устарело с 90-х годов, я думаю. Также Story.propTypes не имеет смысла ... История имеет состояние. –

+0

центр по-прежнему хорошо работает, должен ли я просто добавить текст в соответствие с div или как бы вы теперь центрировали div? – user3622460

+0

в целом все стили должны выполняться с помощью CSS - в теории браузеры могут начать откатываться от поддержки

в какой-то момент. –

ответ

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

Является ли это более элегантным, чем ваше текущее исправление, зависит от вас.

UPDATE: Если вы хотите, чтобы отделить отображение, от 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]; 
+0

Мне это нравится - Я пытаюсь – user3622460

0

Выражение <curSlide/> просто компилируется в 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> 
+0

Не удалось получить const {Slide} = this.props.name, чтобы не выдавать ошибку. Я решил проблему, установив const в this.props.name и вернув функцию с рядом операторов if else, пытающихся совместить слайд. Это не очень, но это работает. Однако я готов к лучшему решению. – user3622460

+0

Я думаю, вы пропустили точку. Я не думаю, что вы должны попытаться передать «имя» компонента. Просто передайте дочерний компонент, который будет отображаться ...в идеале с помощью детей (отредактировано выше) –

Смежные вопросы