Почему мы не можем вызвать ReactDOM или реагировать непосредственно в браузере?

#javascript #reactjs #react-dom

Вопрос:

Я новичок в реагировании и все еще пытаюсь понять, как это работает.

Я понимаю, что в нашем коде React перед «компиляцией» мы можем использовать React.createElement и ReactDOM.render делать всевозможные вещи, но после того, как код будет скомпилирован и запущен на клиенте, предположим, я хотел динамически создать новый узел DOM с одним из моих компонентов.

Добавление некоторого кода для дальнейшего объяснения

Это мое index.js:

 import React from 'react'
import ReactDOM from 'react-dom'

class HelloWorld extends React.Component {

    render() {
        return (
            <div>
                Hello World!
            </div>
        )
    }

}

ReactDOM.render(
    //React Element,
    <HelloWorld />,
    //where to render the Element to
    document.getElementById('hello')
)
 

Это прекрасно работает. Однако , когда я пытаюсь динамически добавить компонент «в реальном времени» через консоль devtools и ввести React.createElement , я получаю:

React is not defined

То же самое и с реактивностью. Они недоступны через консоль? Вероятно, в моем понимании чего-то не хватает, и я думаю об этом неправильно, но как именно React и ReactDOM не определено, если мой index.js смог ли призвать ReactDOM.render ? Спасибо!

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

1. Я предполагаю, что вы используете приложение create-react-app? Потому что вы абсолютно точно можете включить два сценария реакции напрямую и вызвать ReactDOM в любом месте, где вам нравится. Просто не в скомпилированном CRA, потому что модули, которые вы пишете, объединены в один изолированный сценарий. Однако следует отметить, что на самом деле вы не должны создавать элементы на лету подобным образом; например, в react вы добавляете новый объект в массив состояний; это перезапустит вашу функцию визуализации и автоматически добавит новый элемент (поскольку вы написали функцию визуализации соответствующим образом).

2. Вот пример недавно созданных узлов DOM: codesandbox.io/s/winter-meadow-ebgov?file=/src/App.js

3. Когда я нажал вкладку «Консоль» в левом нижнем углу панели «Браузер» по вашей ссылке и попытался ввести React или ReactDOM, она все равно дала мне «не определено». Я думаю, вы пытаетесь объяснить, что ReactDOM работает в коде React, что он делает и в моем коде React: я вижу, как отображается компонент HelloWorld. Я пытаюсь понять, почему я не могу сделать это «на лету» прямо из браузера.

4. Я не использовал create-react-app — я предполагаю, что это команда для создания приложения react? Просто добавил все (webpack, babel, загрузчики и webpack-dev-сервер) с нуля, следуя базовому учебнику. Спасибо!

5. Да, но вы также используете webpack, поэтому React/ReactDOM снова не видны на консоли. Мой пример codesandbox указывал на то, что то, что вы пытаетесь сделать, в любом случае не обязательно. Опять же: webpack берет модули ES6, использующие импорт и экспорт, и компилирует их в один сценарий, изолированный от общего пространства имен. Вы не можете получить доступ ни к чему внутри с консоли, потому что все это заключено в большую функцию. Однако вам это не нужно и не следует делать.

Ответ №1:

React и ReactDOM можно использовать в консоли, если:

  1. Вы экспортируете то, что вам нужно в глобальной области, из точки входа webpack. Например:

    export {React, ReactDOM, LeaveStats }

  2. Пакет, сгенерированный из webpack, включается в HTML-страницу с помощью немодульного скрипта
  3. Webpack настроен для вывода «библиотеки» примерно так:
 module.exports = {
    entry: './app/LeaveStats.js',
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: 'bundle.js',
        library: 'ReactApp' // <-- this will allow us access to whatever is exported in ./app/LeaveStats.js
    },
    module: {
        rules: [
            { test: /.js$/, use: 'babel-loader' },
        ]
    },
    mode: 'development'
}
 

Затем вы можете получить доступ к React ReactDOM LeaveStats глобальной области и из нее , например:

 ReactApp.ReactDOM.render(
    ReactApp.React.createElement(ReactApp.LeaveStats), 
    document.getElementById("mydiv")
)
 

Не то чтобы я действительно использовал бы это, но это помогло мне понять несколько вещей на пути к этому моменту.

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

1. К вашему сведению: Накопительный пакет имеет другую конфигурацию для отображения экспортированных элементов в их пакете. Во-первых, вы не можете использовать формат «es» (вместо этого используйте «umd»), потому что в противном случае вам нужно было бы включить пакет в качестве «модуля», чтобы он не был доступен снаружи. Затем вам нужно указать выходное имя, с помощью которого вы можете получить доступ.