Dynamic 反应动态标记名

Dynamic 反应动态标记名,dynamic,reactjs,components,Dynamic,Reactjs,Components,假设以下和所有组件/fus/fci/ssg只有一个带有站点道具的h1。我想了解为什么它是一个有效的react元素,但这些元素的渲染效果并不相同。一个有h1元素,另一个没有。其想法是不为不同站点创建带有切换的大型组件,每个站点将根据导航选择进行交换。我没有看到任何关于这方面的文件,除非我错过了 {this.state.renderSite} <Fci site="Fci"/> import React from 'react';

假设以下和所有组件/fus/fci/ssg只有一个带有站点道具的h1。我想了解为什么它是一个有效的react元素,但这些元素的渲染效果并不相同。一个有h1元素,另一个没有。其想法是不为不同站点创建带有切换的大型组件,每个站点将根据导航选择进行交换。我没有看到任何关于这方面的文件,除非我错过了

{this.state.renderSite}
<Fci site="Fci"/>
import React from 'react';                                                 
import styles from './App.css';                                            
import Nav from '../components/Nav.js'                                     
import Fus from '../components/Fus.js'                                     
import Fci from '../components/Fci.js'                                     
import Ssg from '../components/Ssg.js'                                     

export default class App extends React.Component {                         
  constructor(props) {                                                     
    super(props);                                                          
    this.state = {renderSite: '', site: 'default' };                       
    this.pickSite = this.pickSite.bind(this);                              
  }                                                                        

  pickSite(site){                                                          
    this.setState({renderSite: React.createElement(site, {"site":site})}); 
    this.setState({site: site});                                           
    console.log( React.isValidElement(this.state.renderSite));             
}                                                                          

  render() {                                                               
    return (                                                               
      <div className={styles.app}>                                         
      <Nav site={this.pickSite.bind(this)} /> 
      {this.state.renderSite}                  
      <Fci site="Fci"/>                                                    
      </div>                                                               
    );                                                                     
  }                                                                        
}                                                                          
{this.state.renderSite}

import React from 'react';                                                 
import styles from './App.css';                                            
import Nav from '../components/Nav.js'                                     
import Fus from '../components/Fus.js'                                     
import Fci from '../components/Fci.js'                                     
import Ssg from '../components/Ssg.js'                                     

export default class App extends React.Component {                         
  constructor(props) {                                                     
    super(props);                                                          
    this.state = {renderSite: '', site: 'default' };                       
    this.pickSite = this.pickSite.bind(this);                              
  }                                                                        

  pickSite(site){                                                          
    this.setState({renderSite: React.createElement(site, {"site":site})}); 
    this.setState({site: site});                                           
    console.log( React.isValidElement(this.state.renderSite));             
}                                                                          

  render() {                                                               
    return (                                                               
      <div className={styles.app}>                                         
      <Nav site={this.pickSite.bind(this)} /> 
      {this.state.renderSite}                  
      <Fci site="Fci"/>                                                    
      </div>                                                               
    );                                                                     
  }                                                                        
}                                                                          
从“React”导入React;
从“/App.css”导入样式;
从“../components/Nav.js”导入导航
从“../components/Fus.js”导入Fus
从“../components/Fci.js”导入Fci
从“../components/Ssg.js”导入Ssg
导出默认类App扩展React.Component{
构造器(道具){
超级(道具);
this.state={renderSite:'',site:'default'};
this.pickSite=this.pickSite.bind(this);
}                                                                        
pickSite(site){
this.setState({renderSite:React.createElement(site,{“site”:site})});
this.setState({site:site});
log(React.isValidElement(this.state.renderSite));
}                                                                          
render(){
报税表(
{this.state.renderSite}
);                                                                     
}                                                                        
}                                                                          
导航

import React from 'react';                                                 
import styles from './App.css';                                            
import Nav from '../components/Nav.js'                                     
import Fus from '../components/Fus.js'                                     
import Fci from '../components/Fci.js'                                     
import Ssg from '../components/Ssg.js'                                     

export default class App extends React.Component {                         
  constructor(props) {                                                     
    super(props);                                                          
    this.state = {renderSite: '', site: 'default' };                       
    this.pickSite = this.pickSite.bind(this);                              
  }                                                                        

  pickSite(site){                                                          
    this.setState({renderSite: React.createElement(site, {"site":site})}); 
    this.setState({site: site});                                           
    console.log( React.isValidElement(this.state.renderSite));             
}                                                                          

  render() {                                                               
    return (                                                               
      <div className={styles.app}>                                         
      <Nav site={this.pickSite.bind(this)} /> 
      {this.state.renderSite}                  
      <Fci site="Fci"/>                                                    
      </div>                                                               
    );                                                                     
  }                                                                        
}                                                                          
import React from 'react';

export default class Nav extends React.Component {
        constructor(props) {
            super(props);
            this.update = this.update.bind(this);
        }

        update(e) {
           this.props.site(e.target.dataset.site);
        }

        render(){ 
            return ( 
                <div>
                    <button onClick={this.update} data-site="Ssg"> SSG </button>
                    <button onClick={this.update} data-site="Fci"> FCI </button>
                    <button onClick={this.update} data-site="Fus"> FUS </button>
                </div>
                     );
        }       
}
从“React”导入React;
导出默认类Nav.Component{
建造师(道具){
超级(道具);
this.update=this.update.bind(this);
}
更新(e){
this.props.site(例如target.dataset.site);
}
render(){
报税表(
SSG
FCI
福斯
);
}       
}

问题在于,当您创建要传递字符串(
数据站点
值)而不是组件引用的元素时。结果是这样的:

import React from 'react';                                                 
import styles from './App.css';                                            
import Nav from '../components/Nav.js'                                     
import Fus from '../components/Fus.js'                                     
import Fci from '../components/Fci.js'                                     
import Ssg from '../components/Ssg.js'                                     

export default class App extends React.Component {                         
  constructor(props) {                                                     
    super(props);                                                          
    this.state = {renderSite: '', site: 'default' };                       
    this.pickSite = this.pickSite.bind(this);                              
  }                                                                        

  pickSite(site){                                                          
    this.setState({renderSite: React.createElement(site, {"site":site})}); 
    this.setState({site: site});                                           
    console.log( React.isValidElement(this.state.renderSite));             
}                                                                          

  render() {                                                               
    return (                                                               
      <div className={styles.app}>                                         
      <Nav site={this.pickSite.bind(this)} /> 
      {this.state.renderSite}                  
      <Fci site="Fci"/>                                                    
      </div>                                                               
    );                                                                     
  }                                                                        
}                                                                          
React.createElement("Fci");
const componentMap = {
    "Fci": Fci,
    "Fus": Fus,
    "Ssg": Ssg
}
与之相反:

import React from 'react';                                                 
import styles from './App.css';                                            
import Nav from '../components/Nav.js'                                     
import Fus from '../components/Fus.js'                                     
import Fci from '../components/Fci.js'                                     
import Ssg from '../components/Ssg.js'                                     

export default class App extends React.Component {                         
  constructor(props) {                                                     
    super(props);                                                          
    this.state = {renderSite: '', site: 'default' };                       
    this.pickSite = this.pickSite.bind(this);                              
  }                                                                        

  pickSite(site){                                                          
    this.setState({renderSite: React.createElement(site, {"site":site})}); 
    this.setState({site: site});                                           
    console.log( React.isValidElement(this.state.renderSite));             
}                                                                          

  render() {                                                               
    return (                                                               
      <div className={styles.app}>                                         
      <Nav site={this.pickSite.bind(this)} /> 
      {this.state.renderSite}                  
      <Fci site="Fci"/>                                                    
      </div>                                                               
    );                                                                     
  }                                                                        
}                                                                          
React.createElement(Fci);
使用字符串将创建一个简单的HTML元素,而不是具有自己呈现内容的组件

import React from 'react';                                                 
import styles from './App.css';                                            
import Nav from '../components/Nav.js'                                     
import Fus from '../components/Fus.js'                                     
import Fci from '../components/Fci.js'                                     
import Ssg from '../components/Ssg.js'                                     

export default class App extends React.Component {                         
  constructor(props) {                                                     
    super(props);                                                          
    this.state = {renderSite: '', site: 'default' };                       
    this.pickSite = this.pickSite.bind(this);                              
  }                                                                        

  pickSite(site){                                                          
    this.setState({renderSite: React.createElement(site, {"site":site})}); 
    this.setState({site: site});                                           
    console.log( React.isValidElement(this.state.renderSite));             
}                                                                          

  render() {                                                               
    return (                                                               
      <div className={styles.app}>                                         
      <Nav site={this.pickSite.bind(this)} /> 
      {this.state.renderSite}                  
      <Fci site="Fci"/>                                                    
      </div>                                                               
    );                                                                     
  }                                                                        
}                                                                          
您可以创建如下组件映射:

import React from 'react';                                                 
import styles from './App.css';                                            
import Nav from '../components/Nav.js'                                     
import Fus from '../components/Fus.js'                                     
import Fci from '../components/Fci.js'                                     
import Ssg from '../components/Ssg.js'                                     

export default class App extends React.Component {                         
  constructor(props) {                                                     
    super(props);                                                          
    this.state = {renderSite: '', site: 'default' };                       
    this.pickSite = this.pickSite.bind(this);                              
  }                                                                        

  pickSite(site){                                                          
    this.setState({renderSite: React.createElement(site, {"site":site})}); 
    this.setState({site: site});                                           
    console.log( React.isValidElement(this.state.renderSite));             
}                                                                          

  render() {                                                               
    return (                                                               
      <div className={styles.app}>                                         
      <Nav site={this.pickSite.bind(this)} /> 
      {this.state.renderSite}                  
      <Fci site="Fci"/>                                                    
      </div>                                                               
    );                                                                     
  }                                                                        
}                                                                          
React.createElement("Fci");
const componentMap = {
    "Fci": Fci,
    "Fus": Fus,
    "Ssg": Ssg
}
然后从字符串中可以解析组件引用:

import React from 'react';                                                 
import styles from './App.css';                                            
import Nav from '../components/Nav.js'                                     
import Fus from '../components/Fus.js'                                     
import Fci from '../components/Fci.js'                                     
import Ssg from '../components/Ssg.js'                                     

export default class App extends React.Component {                         
  constructor(props) {                                                     
    super(props);                                                          
    this.state = {renderSite: '', site: 'default' };                       
    this.pickSite = this.pickSite.bind(this);                              
  }                                                                        

  pickSite(site){                                                          
    this.setState({renderSite: React.createElement(site, {"site":site})}); 
    this.setState({site: site});                                           
    console.log( React.isValidElement(this.state.renderSite));             
}                                                                          

  render() {                                                               
    return (                                                               
      <div className={styles.app}>                                         
      <Nav site={this.pickSite.bind(this)} /> 
      {this.state.renderSite}                  
      <Fci site="Fci"/>                                                    
      </div>                                                               
    );                                                                     
  }                                                                        
}                                                                          
React.createElement(componentMap[site], {site: site});

或者您可以从
Nav
传递组件引用:

import React from 'react';                                                 
import styles from './App.css';                                            
import Nav from '../components/Nav.js'                                     
import Fus from '../components/Fus.js'                                     
import Fci from '../components/Fci.js'                                     
import Ssg from '../components/Ssg.js'                                     

export default class App extends React.Component {                         
  constructor(props) {                                                     
    super(props);                                                          
    this.state = {renderSite: '', site: 'default' };                       
    this.pickSite = this.pickSite.bind(this);                              
  }                                                                        

  pickSite(site){                                                          
    this.setState({renderSite: React.createElement(site, {"site":site})}); 
    this.setState({site: site});                                           
    console.log( React.isValidElement(this.state.renderSite));             
}                                                                          

  render() {                                                               
    return (                                                               
      <div className={styles.app}>                                         
      <Nav site={this.pickSite.bind(this)} /> 
      {this.state.renderSite}                  
      <Fci site="Fci"/>                                                    
      </div>                                                               
    );                                                                     
  }                                                                        
}                                                                          
<button onClick={this.update.bind(this, Ssg, "Ssg"}> SSG </button>

update(component, site, e) {
    this.props.site(component, site);
}

pickSite(component, site) {
    React.createElement(component, {site: site});
}
SSG
更新(组件、站点、e){
此.props.site(组件、站点);
}
拾取站点(组件、站点){
createElement(组件,{site:site});
}

你能发布
导航组件吗?@Aaron将导航组件添加得很好!另一方面,与其创建元素,并将(对)已创建元素的引用完全存储在状态中,我建议只将对组件的引用存储在您的状态中,并在渲染函数中创建实际的元素。保持代码干净我同意@wintvelt,事实上我只会将字符串存储在state中,并在
render
函数中进行所有元素映射和创建。您可以创建一个子渲染函数,如
renderSite()
,将其隔离。@Aaron我不喜欢在渲染中内部混合jsx和js的想法;但是,假设状态良好,则在出现意外令牌时同样会失败。混合是正常的吗?为什么createElement在这种情况下工作而不是jsx?请参阅一个简单的方法,以避免
createElement()
@jbustamovej该方法在这种情况下不工作,因为
Fci
是一个组件而不是html标记。