Можно ли динамически загружать компоненты react из строки?

#javascript #reactjs

Вопрос:

У нас есть конструктор компонентов, это графический интерфейс, который пользователи могут использовать для создания простого шаблона, содержащего различные HTML-компоненты (например, кнопки добавления, текстовые поля и т.д.). Затем пользователи могут экспортировать этот код в виде файла JavaScript, содержащего код реакции, подобный этому:

 import React from 'react';
import * from '@material-ui/core';

const Calculator = () => {
    return (<div>
        <Button style={{height: 50, width: 50}}>1</Button>
        <Button style={{height: 50, width: 50}}>5</Button>
        <Button style={{height: 50, width: 100}}>add</Button>
        <Typography variant='contained' style={{fontSize: "23px"}}>answer</Typography>
    </div>);
};

export default Calculator;
 

У нас есть еще один вариант в CMS, где пользователи могут загружать эти экспортированные файлы. Мы сохраняем содержимое этих файлов в виде строки в базе данных. Затем пользователи могут выбрать в CMS один из загруженных ими файлов.

Наша цель-динамически загрузить строку в качестве компонента React.

 
const ComponentContainer = ({fileContentsAsString}) => {

    // Do some black magic to load the calculator component and render it.
    
    return (
        <Calculator/>
    );
};

export default ComponentContainer;
 

Основная причина, по которой мы хотим этого, заключается в том, что наши разработчики могут создавать небольшие интерфейсы для конкретных продуктов, которые имеют согласованный стиль. Идея заключается в том, что конструктор компонентов экспортирует базовый код реакции, а затем наши разработчики могут заполнить детали, чтобы подключить его к бэкэнду, например:

 import React, {useState} from 'react';
import {Button, Typography} from "@material-ui/core";

const Calculator = () => {

    const [number1, setNumber1] = useState()
    const [number2, setNumber2] = useState()

    const [answer, setAnswer] = useState(0)

    async function add() {
        await fetch(`http://localhost:9001/api/add`,
            {
                method: "POST",
                body: JSON.stringify([number1, number2]),
                headers: {
                    'Content-type': 'application/json'
                }
            }).then(async response => {
                const data = await response.json()
                setAnswer(data)
        })
    }

    return (
        <div>
            <Button style={{height: 50, width: 50}} variant="contained" color="primary" onClick={() => setNumber1(1)}>1</Button>
            <Button style={{height: 50, width: 50}} variant="contained" color="primary" onClick={() => setNumber2(5)}>5</Button>
            <Button style={{height: 50, width: 100}} variant="contained" color="primary" onClick={() => add()}>add</Button>
            <Typography variant='contained' style={{fontSize: "23px"}}>answer: {answer}</Typography>
        </div>
    );
};

export default Calculator;
 

Мы застряли на том, как действовать здесь, и задаемся вопросом, возможно ли вообще то, чего мы хотим достичь. Мы предполагаем, что это должно быть потому, что есть онлайн-редакторы, которые делают это.

Комментарии:

1. Ладно, я думаю, что вся эта идея неверна, и мы думаем решить ее сейчас, используя сгенерированный код реакции в качестве шаблона и разместив его на другом сервере. Затем мы загружаем страницу в iframe.