Supongamos que tengo:

import MyComponent from "../somewhere"

Puedo crear una instancia de ella haciendo:

<MyComponent myprops={myprops} />

¿Pero puedo crear uno mediante programación desde MyComponent y agregar accesorios?


Por ejemplo, tengo una lista de referencias de componentes:

import comp1 from "somewhere"
import comp2 from "somewhere"
import comp3 from "somewhere"

var myComponents = [
    comp1, comp2, comp3
];

Y ahora tengo que tomar uno de ellos y ponerlo a la vista:

var randomComponent = myComponents[Math.random() * 3 | 0];

// render
render(){
    return randomComponent; // this doesn't work and certain props have to be added
}

¿Hay alguna manera de evitar hacer lo siguiente y lograr lo mismo?

var myComponents = [
    <comp1 props=... />, <comp2 props=... />, <comp3 props=... />
];
3
Derek 朕會功夫 17 feb. 2017 a las 04:58

3 respuestas

La mejor respuesta

Puede hacer lo siguiente:

var RandomComponent = myComponents[Math.random() * 3 | 0];

render() {
    return <RandomComponent props={foobar} />;
}

Lo anterior se demuestra en el Reaccionar documentos donde se menciona lo siguiente:

No puede usar una expresión general como el tipo de elemento React. Si desea utilizar una expresión general para indicar el tipo de elemento, simplemente asígnelo primero a una variable en mayúscula . (énfasis mío)

La razón por la cual el nombre del componente debe se escribe con mayúscula es porque se tratará como un componente integrado (componente DOM) si no. Esto funciona porque simplemente se transpuso en esto:

React.createElement(RandomComponent, { props: foobar });

Y RandomComponent todavía se refiere a un componente seleccionado al azar. Si randomComponent está no en mayúscula, puede hacerlo sin JSX así:

React.createElement(randomComponent, { props: foobar });

Simplemente no podrá hacerlo con JSX porque randomComponent está en minúscula y, por cierto, se transpuso en esto:

React.createElement("randomComponent", { props: foobar });

Lo cual es problemático ya que "randomComponent" no se refiere a randomComponent.

4
Andrew Li 17 feb. 2017 a las 02:31

Pensé que iba a compartir. Tenía un caso de uso muy específico para esto usando archivos svg importados, pero creo que esto también funcionaría con componentes. Quería tener un componente de botón que cargara diferentes iconos de svg dado un tipo de utilería.

import LightBulb from '../my-icons/Lightbulb.svg';

const ICON_TYPES = {
  LightBulb: 'LightBulb',
};

const ICON_TYPE_FILES = {
  [ICON_TYPES.LightBulb]: LightBulb,
};

export default function IconButton({iconType}) {
  const IconComponent = ICON_TYPE_FILES[iconType];
  return (
    <Icon>
      <IconComponent />
    </Icon>
   );
};
IconButton.ICON_TYPES = ICON_TYPES

Usando componente:

<IconButton
  iconType={IconButton.ICON_TYPES.LightBulb}
/>
1
Lauren 3 mar. 2020 a las 19:29

Consulte Crear componente de reacción de forma dinámica

var component = myComponents[Math.random()*3 |0];
return React.createElement(component, props);
2
FuzzyTree 17 feb. 2017 a las 02:12