2015-08-12 2 views
0

Я новичок в реакторе, поэтому, пожалуйста, помилуй.React Dynamic Component Naming

Я также прочитал все темы этого, React/JSX Dynamic Component Name и React/JSX dynamic component names в частности. Решения не работали.

Я использую интерфейс стиля табуляции, где пользователь выбирает вкладку и загружает соответствующие материалы. Родительский компонент сохраняет состояние содержимого вкладки, передает соответствующие реквизиты дочернему контенту. Затем этот ребенок загружает правильный компонент контента (как собственный ребенок).

var TabbedContent = React.createClass({ 

loadMenu: function() { 
    var menus=this.props.carDivState.vehicleDetailState; 
    for (key in menus) { 
     if (menus.hasOwnProperty(key)) { 
      if (menus[key]) { 
       var Component='TabbedContent'+key; 
       return <Component />; 
      }   
     } 
    } 
}, 

render: function() { 
    return (
     <div className="TabbedContent"> 
      <div className="contentWrapper"> 
       {this.loadMenu()} 
      </div> 
     </div> 
    ) 
} 

}); 

loadMenu проходит через опоры, пока не найдет истинную опору. Затем он возвращает этот ключ (например, «Обзор») и создает переменную (например, Component = 'TabbledContentOverview').

Однако мой код возвращает HTML тег <tabbedcontentoverview></tabbedcontentoverview>

Вопрос

Как получить Реагировать вернуть компонент Реагировать вместо HTML тега? Кажется, я использую правильные капитализированные соглашения об именах. Я читал документы в Facebook. Я просто не понимаю.

+0

Я хотел бы найти другой способ сделать это, ау как это похоже на рецепт катастрофы ... Почему бы не использовать реквизиты типа ''? – elclanrs

+0

Насколько я понимаю ваше решение, вы должны передать ключ в качестве опоры, а затем сохранить все потенциальное содержимое с вкладками в одном компоненте? Я беспокоюсь, что по мере того, как разделы масштабируются, я останусь с одним гигантским и громоздким компонентом. Что мне не хватает или почему я ошибаюсь? Спасибо, что нашли время ответить! –

+0

Это было мое предложение, но я думаю, это зависит от того, сколько альтернатив вам нужно. В любом случае вы можете создавать динамические компоненты, в конце концов, JSX является «просто JavaScript»; существует свойство 'displayName', которое можно использовать для динамического создания классов с помощью' React.createClass' – elclanrs

ответ

0

https://github.com/vasanthk/react-bits/blob/master/patterns/30.component-switch.md

import HomePage from './HomePage.jsx'; 
import AboutPage from './AboutPage.jsx'; 
import UserPage from './UserPage.jsx'; 
import FourOhFourPage from './FourOhFourPage.jsx'; 

const PAGES = { 
    home: HomePage, 
    about: AboutPage, 
    user: UserPage 
}; 

const Page = (props) => { 
    const Handler = PAGES[props.page] || FourOhFourPage; 

    return <Handler {...props} /> 
}; 

// The keys of the PAGES object can be used in the prop types to catch dev-time errors. 
Page.propTypes = { 
    page: PropTypes.oneOf(Object.keys(PAGES)).isRequired 
}; 
1

Для создания элемента из него (в JS или JSX) вам нужно иметь ссылку на фактический класс.

Держите карту ключей для React классов (т.е. tabbedChildren), и просто создать этот элемент, используя API JS:

var childComponent = tabbedChildren[key] 
return React.createElement(childComponent) 

https://facebook.github.io/react/docs/top-level-api.html

+0

Я попытался реализовать ваше решение (и для документов FB), но я получаю ошибку типа. Я не знаком с записью скобок, конкатенирующей с компонентом React. Я подозреваю, что я ошибаюсь.Вот [скрипка] (http://jsfiddle.net/o8yLv1tb/) –

+0

Я имел в виду наличие JS-карты ключей <=> и получить необходимый компонент по ключу. Я отредактировал ответ, чтобы его отразить. – lyosef

1

Прежде всего, если вы используете Bootstrap для вашего приложения, Я предлагаю вам использовать react-bootstrap`s tab. Если вы этого не сделаете, я бы посоветовал вам хотя бы взглянуть на реализацию их TabPane и TabbedArea.

Вот пример того, как это выглядит в вашем приложении:

const tabbedAreaInstance = (
    <TabbedArea defaultActiveKey={2}> 
    <TabPane eventKey={1} tab='Tab 1'>TabPane 1 content</TabPane> 
    <TabPane eventKey={2} tab='Tab 2'>TabPane 2 content</TabPane> 
    <TabPane eventKey={3} tab='Tab 3' disabled>TabPane 3 content</TabPane> 
    </TabbedArea> 
); 

React.render(tabbedAreaInstance, mountNode); 

Теперь, возвращаясь к вашему вопросу, если вы хотите создать компонент по имени, просто вызовите React.createElement внутри вашего loadMenu:

loadMenu: function() { 
    var menus=this.props.carDivState.vehicleDetailState; 
    for (key in menus) { 
     if (menus.hasOwnProperty(key)) { 
      if (menus[key]) { 
       return React.createElement('TabbedContent'+key); 
      }   
     } 
    } 
} 
+0

Спасибо за совет Bootstrap! Я обязательно проверю это. Я создал скрипт (http://jsfiddle.net/hw0oyzod/3/), реализующий (или, по крайней мере, пытающийся реализовать) ваш ответ. Он возвращает HTML-элемент ''. Любая идея, где это происходит неправильно? –