React - 动态返回没有三元组件

时间:2018-03-17 00:11:19

标签: reactjs

import React from 'react';
import {FirstCustomComponent} from './somewhere';
import {SecondCustomComponent} from './somewhere-else';

const ThirdCustomComponent = ({componentTitle, apple, banana}) => (
 componentTitle === 'FirstCustomComponent' 
    ? <FirstCustomComponent apple={apple} banana={banana} />
    : <SecondCustomComponent apple={apple} banana={banana} />

);

export default ThirdCustomComponent;

避免上面代码示例中重复的好方法是什么?我尝试通过设置const DynamicComponent = props.componentTitle然后返回<DynamicComponent apple={props.apple} banana={props.banana} />来动态生成组件,但没有运气。

6 个答案:

答案 0 :(得分:1)

他们有多种方法可以做到这一点,如果您不想将所有元素导入到您的页面中,您可以使用“中间”文件创建包含所有元素的对象,您可以执行以下操作:< / p>

first.js

class First extends Component {
  render(){
    return (
    <div>
      <span>first</span><br/>
      <span>{this.props.title}</span>
    </div>
  )
  }
}

second.js

class Second extends Component {
  render(){
    return (
      <div>
        <span>second</span><br/>
        <span>{this.props.title}</span>
      </div>
    )
  }
}

objects.js

import First from './first.js'
import Second from './second.js'
const objects = {
  "First": First,
  "Second": Second,
}

import objects from './objects'

class Third extends Component {
  render(){
    const Type = objects[this.props.type];
    return (
      <div>
        <Type title={this.props.title}/>
      </div>
    )
  }
}

Main.js

class App extends Component {
  render() {
    return (
      <div className="App">
        <Third title={'hello'} type={'First'} />
      </div>
    );
  }
}

答案 1 :(得分:0)

您可以将组件作为道具传递。该组件必须是有效的反应组件;即返回JSX的函数或React.Component

的实现
const ThirdCustomComponent = ({component: Component, apple, banana}) => (
    <Component apple={apple} banana={banana} />
);

// Using ThirdCustomComponent
import FirstCustomComponent from './FirstCustomComponent';

const apple = {...};
const banana = {...};    

const Container = () => (
  <ThirdCustomComponent 
     component={FirstCustomComponent} 
     apple={apple} 
     banana={banana} 
  />
);

答案 2 :(得分:0)

如果您在React应用程序中使用ES6箭头函数,您可能会喜欢这种方法。它利用了立即调用函数的概念。它只是通用的JavaScript。难道这就是我们为什么一开始就写React的原因吗?好吧,因为我们比使用Angular和Vue的人更聪明... =)

class Dynamic extends React.Component {
  render() {
    return (
      <div>
        {
          (() => {
            switch(this.props.title) {
              case 'one':
                return <One />
              case 'two':
                return <Two />
              default:
                return null            
            }
          })()
        }
      </div>
    )
  }
}

const One = () => <div className="one"> Component One </div>
const Two = () => <div className="two"> Component Two </div>

ReactDOM.render(
  <Dynamic title="one" />,
  document.querySelector('#app')
)

我在Codepen中也加入了example

答案 3 :(得分:0)

const ThirdCustomComponent = ({componentTitle, apple, banana}) => {
  const DynamicComponent =
    componentTitle === 'FirstCustomComponent'
    ? FirstCustomComponent
    : SecondCustomComponent;

  return React.cloneElement(DynamicComponent, {
    { apple, banana }
  }
};

请尝试上面的代码段。

基本上,React.cloneElement(Component, props)是解决方案。

答案 4 :(得分:0)

你很亲密;问题是props.componentTitle仍然是一个字符串,但JSX需要一个实际的Component。具体而言,(如this SO answer中所述),<DynamicComponent />会编译为React.createElement(DynamicComponent , {}),因此您可以执行此类操作

const FirstCustomComponent = () => (
  <p>First</p>
)
const SecondCustomComponent = () => (
  <p>Second</p>
)

const ThirdCustomComponent = ({componentTitle}) => {
  const DynamicComponent = componentTitle === 'FirstCustomComponent' 
      ? FirstCustomComponent
      : SecondCustomComponent;
  return <DynamicComponent />;
}

ReactDOM.render(<div>
  <ThirdCustomComponent componentTitle="FirstCustomComponent" />
  <ThirdCustomComponent componentTitle="SecondCustomComponent" />
</div>, document.getElementById("container"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="container" />

答案 5 :(得分:-1)

可能你可以使用类似于下面的代码来实现这一点(假设你想传递组件名而不是组件引用)

&#13;
&#13;
const First = ({a, b}) => <h1>1-{a}-{b}</h1>
const Second = ({a, b}) => <h1>2-{a}-{b}</h1>

const Comp = {
  First,
  Second,
} // we have Babel, ES6 object notation okay

const App = ({title, a, b}) => React.createElement(Comp[title], {a, b}) // just for one-liner, if you know React w/o JSX

/* Same as
const App = ({title, a, b}) => {
  const Tag = Comp[title]
  return <Tag a={a} b={b} />
}
*/

ReactDOM.render(<App a="apple" b="banana" title="First" />, document.getElementById('app'))
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
&#13;
&#13;
&#13;