Как связать node js и react
В прошлых вводных темах весь код приложения определялся на веб-странице:
Hello React
Такой подход хорош для вывода сообщения «Hello React», но в реальности весь код JSX обычно выносится во внешние файлы. Поэтому определим в той же папке, где находится данная веб-страница, новый файл index.jsx :
const rootNode = document.getElementById("app"); // элемент для рендеринга приложения React // получаем корневой элемент const root = ReactDOM.createRoot(rootNode); // рендеринг в корневой элемент root.render( Hello React
// элемент, который мы хотим создать );
Обычно код JSX определяется в файлах с расшиением *.jsx , хотя можно использовать и стандартное расширение js.
И изменим веб-страницу:
Hello React
Вроде бы у нас все то же самое, используется тот же код, только в отдельном файле. Но если мы просто кинем страницу в браузер, то мы столкнемся с ошибкой:

Дело в том, что Babel подтягивает код JSX через AJAX-запросы. Поэтому просто кинуть веб-страницу в браузер у нас не получится, нам надо использовать для обращения к ней веб-сервер, то есть все файлы приложения должны быть размещены на веб-сервере. Здесь не столь важно, какой именно веб-сервер использовать — Apache, Node.js, IIS. Но в рамках данных статей преимущественно будет использоваться Node.js как более демократичный вариант. Поэтому для работы также необходимо установить Node.js.
Подробнее про работу с Node.js можно почитать в соответствующем руководстве.
После установки Node.js в каталог проекта добавим новый файл app.js . То есть в итоге в папке проекта будет три файла:

- index.html
- index.jsx
- app.js
Определим в файле app.js следующий код:
const http = require("http"); const fs = require("fs"); http.createServer(function(request, response) < let filePath = "index.html"; if(request.url !== "/")< // получаем путь после слеша filePath = request.url.substring(1); >fs.readFile(filePath, function(error, data) < if(error)< response.statusCode = 404; response.end("Resourse not found!"); >else < response.end(data); >>); >).listen(3000, function()< console.log("Server started at 3000"); >);
Это простейший веб-сервер на Node.js, который мы бы могли определить в нашей ситуации для наших скромных целей — оправить пользователю страницу index.html со всеми сопутствующими файлами. В частности, в начале подключаем для модуля — http и fs , которые необходимы соответственно для обработки http-запросов и для работы с файлами:
const http = require("http"); const fs = require("fs");
Далее создаем собственно веб-сервер с помощью функции http.createServer() :
http.createServer(function(request, response)
В качестве параметра она принимает функцию, которая будет запускаться для обработки каждого приходящего на сервер запроса. И эта функция имеет два параметра: request — объект, который хранит все данные запроса, и response — объект, который позволяет определить нам ответ на запрос.
В данном случае у нас очень простая ситуация — нам надо отправить статический файл: либо index.html , либо index.jsx . Для этого в начале смотрим на запрошенный путь. Если запрос идет к корню сайта, то есть по адресу «localhost:3000/», то отправляем страницу «index.html». А для всех остальных адресов, в частности, для файла «index.jsx», получаем запрошенный путь
filePath = request.url.substring(1);
Далее с помощью функции fs.readFile() считываем из файловой системы запрошенный файл:
fs.readFile(filePath, function(error, data)И с помощью метода response.end() отправляем считанный данные пользователю:
response.end(data);В конце функция listen() запускает созданный веб-сервер на 3000-м порту, и после этого мы сможем обращаться к приложению по адресу "http://localhost:3000"
.listen(3000, function()< console.log("Server started at 3000"); >);И теперь, когда все готово, запустим приложение. Для этого откроем командную строку/терминал и перейдем с помощью команды cd к папке проекта. Затем запустим приложение с помощью команды
node app.js
После этого в браузере перейдем по адресу "http://localhost:3000", по которому запущен сервер, и нам откроется веб-страница index.html:
В итоге компилятор Babel при запуске страницы подгрузит файл index.jsx и скомпилирует из него код JavaScript, который будет применяться к странице.
Принцип объединения react js и express
Я посмотрел не мало примеров как люди используют react js с node express, все сводятся к тому что мне нужно запускать сервер обработчик запросов на одном порте и сервер клиента через npm start на другом порте. Не понимаю можно ли как-то все держать на одном порте и как это будет выглядеть на релизе.
Отслеживать
задан 30 ноя 2018 в 19:39
Эд Мединский Эд Мединский
23 3 3 бронзовых знака1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Это делается даля того чтоб, фронт и бек разработка не зависели друг от друга и шли параллельно. Есть один сервер который возвращает статические файлы и больше ничего не делает. И есть второй сервер в котором прописана логика работы с данными.
На фронте могут замокать ajax запросы пока не готово API, а бек разработчикам фронт и не нежен.
Самый примитивный пример все на одном сервере
api.js
Логика работы с данными
const express = require('express'); // некая база данных const db = require('./db'); const router = express.Router(); // что-то делаем router.post('/users/:id', async (req, res) => < try < const const user = await db.fetchUserById(id); res.status(200).json(user); >catch (e) < res.sendStatus(500); >>); module.exports = router;index.js
const path = require('path'); const express = require('express'); const bodyParser = require('body-parser'); // Наше API const api = require('./api'); const PORT = process.env.PORT; const indexHTML = path.resolve(__dirname,'../public/index.html'); const app = express(); app.use(bodyParser.json()); // Для статических файлов app.use('/', express.static('public')); // Подключаем API // Теперь мы можем делать ajax запросы // и получить пользователя с id 1 по урлу /api/users/1 app.use('/api', api); app.get('/*', (req, res) => res.sendFile(indexHTML)); app.listen(PORT, () => console.info('Server is running on port:', PORT));Node JS и React - как создать фулстек приложение. Полное руководство
React приложение и бэкенд на NodeJS это хорошее сочетание, которое подойдет для реализации практически любых сервисов. Эта статья поможет вам быстро создать фулстек приложение.
Необходимые инструменты
- NodeJS и npm. Их можно скачать с официального сайта nodejs.org. npm установится автоматически вместе с NodeJS.
- Предпочитаемый IDE, например, Visual Studio Code.
- Опционально, установить git для удобной работы с кодом.
О приложении
В этой статье напишем приложение, которое будет получать и отображать список дел. Структура папок будет выглядеть следующим образом.
app/ frontend/ backend/Создание бэкэнда на NodeJS
Запустим команду в папке app/backend для инициализации проекта:
npm init -yЭта команда создаст файл package.json . Этот файл содержит как общую информацию о проекте (название, версия, описание и т.д.), так и информацию о зависимостях, скрипты для запуска, сборки и тестирования. Для создания сервера будем использовать express. Установим его с помощью команды:
npm i expressСоздадим файл index.js , который будет содержать код для запуска сервера. Этот код запускает веб сервер на порту 3010 , если он не задан в переменных среды.
// backend/index.js const express = require('express'); const PORT = process.env.PORT || 3010; const app = express(); app.use((req, res, next) => < res.setHeader('Access-Control-Allow-Origin', '*'); next(); >); app.listen(PORT, () => < console.log(`Server listening on $`); >);Добавим команду для запуска сервера в package.json . В результате сможем запускать наш сервер с помощью команды npm start .
// backend/package.json . "scripts": < "start": "node ./index.js" >, .Из директории app/backend запустим команду npm start . Если ошибок нет, получим сообщение, что сервер прослушивает порт 3010.
PS C:\tutorials-coding\nodejs-react-app\backend> npm start > backend@1.0.0 start > node ./index.js Server listening on 3010Создание API
API это интерфейс, с помощью которого React приложение будет общаться с веб-сервером, т.е. запрашивать, изменять или удалять данные. В нашем случае мы создадим API для получения списка дел в формате JSON. Создадим файл todo-items.json c объектами todo. Этот массив будем отдавать по запросу /api/todo-items .
Следующий код создает эндпоинт /api/todo-items . React приложение будет отправлять GET запрос на этот эндпоинт.
// backend/index.js // . const todoItems = require('./todo-items.json'); app.get('/api/todo-items', (req, res) => < res.json(< data: todoItems >); >); app.listen(PORT, () => < console.log(`Server listening on $`); >);
Для того чтобы изменения вступили в силу, нужно перезапустить NodeJS сервер. Для остановки скрипта - в терминале, в котором запущен npm start , нужно нажать Ctrl + C ( Command + C ). Далее снова запускаем npm start . Для проверки эндпоинта, в браузере перейдем по адресу http://localhost:3010/api/todo-items . В результате получим, такой ответ.
Создание фронтенда на React
В папке app/ откроем новый терминал и запустим команду для создания React приложения, где frontend имя нашего приложения.
npx create-react-app@latest frontendДождемся установки всех зависимостей. В терминале перейдем в папку frontend .
cd ./frontendУстановим библиотеку bootstrap для дальнейшего использования готовых компонентов.
npm install react-bootstrap bootstrapЗаимпортируем bootstrap.min.css в файле frontend/src/index.js .
import 'bootstrap/dist/css/bootstrap.min.css';Запустим приложение командой npm start .
npm startПолучим следующее сообщение. Перейдем по указанному адресу в браузере.
Compiled successfully! You can now view frontend in the browser. Local: http://localhost:3003 On Your Network: http://192.168.99.1:3003 Note that the development build is not optimized. To create a production build, use npm run build.Отправка HTTP запроса из React в NodeJS
К этому моменту у нас уже есть рабочий сервер, который умеет принимать запросы и отдавать данные. Сделаем запрос на /api/todo-items из React приложения. Для этого вызовем функцию fetch из хука useEffect в файле App.js .
// frontend/src/App.js import < useState, useEffect >from 'react'; import Form from 'react-bootstrap/Form'; import './App.css'; function App() < const [todoItems, setTodoItems] = useState([]); useEffect(() => < fetch('http://localhost:3010/api/todo-items') .then((res) =>res.json()) .then((result) => setTodoItems(result.data)); >, []); return (); > export default App;( className="app__todo-item"> /> /> ))>
Открыв приложение в браузере, получим такой результат. Исходный код
Хуки useTransition и useDeferredValue в ReactJS 18
год назад · 3 мин. на чтение
В React 18, релиз которого произошел в марте 2022, появилось много новых инструментов для написания производительных и отзывчивых приложений. Одним из заметных изменений является механизм рендеринга с новой ключевой концепцией: конкурентный рендеринг (concurrent rendering).
В этой статье повнимательнее рассмотрим два новых хука: useTransition() и useDeferredValue() . Эти два хука дают возможность определять приоритет обновления состояния, или, скорее, указывать, является ли обновление менее важным, чем другие, и откладывать его в пользу более срочных.
- Срочные обновления: отражают прямое взаимодействие, такое как набор текста, клики, нажатия и т. д., т.е. то с чем взаимодействует пользователь. Когда вы вводите текст в поле ввода, вы хотите сразу увидеть введенный вами текст. В противном случае UI будет казаться медленным и подлагивать. Поэтому мы хотим сделать такие обновления приоритетным.
- Обычные обновления: переход пользовательского интерфейса из одного вида в другой. Пользователи знают, что представление должно измениться или обновиться (например, когда ожидается ответ на запрос данных). Даже если есть небольшая задержка, это можно рассматривать как ожидаемое поведение, и это не будет восприниматься как медлительность приложения.
Хук useTransition() и функция startTransition()
До React 18 все обновления состояния помечались как "срочные". Это означает, что все обновления состояния обрабатывались одинаково с одинаковым приоритетом. С помощью useTransition() теперь можно пометить некоторые обновления состояния как несрочные.
Когда использовать useTransition() ?
Одним из примеров может быть список товаров с параметрами фильтрации. Когда вы переключаете чекбоксы, чтобы выбрать размер или цвет одежды, вы ожидаете, что чекбоксы сразу же отобразят отмеченное или снятое состояние. А сам список товаров, которые необходимо обновить согласно фильтрам, может быть отдельным и менее срочным обновлением.
Как использовать useTransition() ?
function App() < const [isPending, startTransition] = useTransition(); const [searchQuery, setSearchQuery] = useState(''); // запрос данных, который занимает некоторое время const filteredResults = getProducts(searchQuery); function handleQueryChange(event) < startTransition(() =>< // оборачивая setSearchQuery() в startTransition(), // мы помечаем эти обновления как менее важные setSearchQuery(event.target.value); >); > return (/> Loading. > />); >Хук useDeferredValue()
useDeferredValue() очень похож на useTransition() в том, что он позволяет отложить несрочное обновление состояния, но применяется его к части дерева. Это похоже методы debounce и throttle, которые мы часто используем для отложенных обновлений. React будет работать с такими обновлениями, как только завершатся срочные обновления.
Когда использовать useDeferredValue() ?
С помощью useTransition() вы сами решаете, когда конкретное обновление состояния может быть помечено как менее срочное. Но иногда такой возможности может и не быть, например, если фрагмент кода находится в сторонней библиотеке. В таких случаях можно воспользоваться хуком useDeferredValue() . С помощью useDeferredValue() вы можете обернуть значение и пометить его изменения как менее важные и, следовательно, отложить повторный рендеринг. useDeferredValue() будет возвращать предыдущее значение до тех пор, пока есть более срочные обновления для завершения и отображения дерева с обновленным значением.
Как использовать useDeferredValue() ?
Итоги
Эти два новых хука позволяют сделать интерфейсы максимально отзывчивыми, даже в сложных приложениях с большим количеством повторных рендерингов, отдавая приоритет обновлениям, которые имеют решающее значение для взаимодействия с пользователем, и помечая некоторые другие как менее важные. Это не означает, что нужно оборачивать все состояния этими хуками. Их следует использовать в крайнем случае, если приложение или компоненты не могут быть оптимизированы другими способами (например, при помощи lazy loading’а, пагинации, веб-воркеров и т. д.).
Как настроить Node.js Express сервер для React
Это руководство поможет вам разработать простое приложение на React и подключить его к серверу, созданному с использованием Node.js.
React – это библиотека JavaScript для разработки пользовательских интерфейсов. Она позволяет создавать эффективные и масштабируемые веб-приложения, основанные на компонентной архитектуре.
Express.js – это минималистичный и гибкий веб-фреймворк для Node.js, который облегчает разработку веб-приложений и API. Он предоставляет простой интерфейс и набор функций, позволяющих быстро создавать серверы и маршрутизировать запросы.
Введение
Это руководство поможет вам разработать простое приложение на React и подключить его к серверу, созданному с использованием Node.js. Мы начнем с создания React приложения с помощью команды create-react-app , а затем настроим его подключение к серверу Node.js c помощью proxy
Необходимые условия
Для успешного выполнения данного гайда будет полезно иметь следующее:
- Знакомство/небольшой опыт работы с Node.js, Express, npm и React.js.
- Установленный Node.js.
- Текстовый редактор, предпочтительно VS Code.
- Веб-браузер, в данном случае Google Chrome.
Настройка структуры папок
Файловая структура приложения
Первым шагом будет создание корневой папки для нашего приложения с именем express-react-app , в котором будут содержаться все файлы приложения. Затем мы создадим папку client , которая будет содержать все файлы React приложения.
Папка node_modules будет автоматически создана при установке пакетов NPM и будет содержать все пакеты NPM для файла server.js .
Далее нам потребуется создать файл server.js . В этом файле будет размещен сервер Express, который будет выступать в качестве нашего бэкенда.
Файл package.json будет автоматически сгенерирован, когда в терминале будет выполнена команда npm init -y .
Создание React приложения
Из терминала перейдите в корневую директорию с помощью команды cd и выполните следующие команды:
$cd express-react-app $npx create-react-app client
Вышеуказанные команды создадут React приложение названием client внутри корневой директории.
Настройка сервера Express
Следующий шаг состоит в создании сервера Express в файле server.js .
Из терминала перейдите в корневую директорию и выполните следующую команду:
$npm init -y
Команда автоматически сгенерирует файл package.json . Затем нам потребуется выполнить следующую команду для установки Express, и она будет сохранена в качестве зависимости в файле package.json .
$npm install express --save
Теперь отредактируйте файл server.js следующим образом:
const express = require('express'); //Строка 1 const app = express(); //Строка 2 const port = process.env.PORT 5000; //Строка 3 // Сообщение о том, что сервер запущен и прослушивает указанный порт app.listen(port, () => console.log(`Listening on port $`)); //Строка 6 // Создание GET маршрута app.get('/express_backend', (req, res) => < //Строка 9 res.send(< express: 'YOUR EXPRESS BACKEND IS CONNECTED TO REACT' >); //Строка 10 >); //Строка 11
Строки 1 и 2 – подключают модуль Express и позволяют использовать его внутри файла server.js .
Строка 3 – Установка порта, на котором будет работать сервер Express.
Строка 6 – будет отображено сообщение в консоли о том, что сервер работает исправно.
Строка 9 и 11 – установка GET маршрута, который позже мы будем получать из нашего клиентского React приложения.
Настройка proxy
На этом шаге Webpack Development Server был автоматически сгенерирован при выполнении команды create-react-app . Наше React приложение работает на Webpack Development Server на стороне фронденда.
Webpack Development Server (WDS) – это инструмент, который помогает разработчикам вносить изменения во фронтенд веб-приложения и автоматически отображает эти изменения в браузере без необходимости обновления страницы.
Мы можем настроить проксирование запросов API с клиентской стороны на API на серверной стороне. API на серверной стороне (Express сервер) будет работать на порту 5000.
Сначала настройте прокси для перехода в директорию client и найдите файл package.json . Добавьте следующую строку в него:
“proxy”: “http://localhost:5000”
Измененный файл package.json будет выглядеть следующим образом:
< "name": "client", "version": "0.1.0", "private": true, "dependencies": < "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "react": "^18.2.0", "react-dom": "^18.2.0", "react-scripts": "5.0.1", "web-vitals": "^2.1.4" >, "scripts": < "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" >, "eslintConfig": < "extends": [ "react-app", "react-app/jest" ] >, "browserslist": < "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] >, "proxy": "http://localhost:5000" >
Измененный файл package.json позволит Webpack проксировать запросы API на сервер бэкенда Express, работающий на порту 5000.
Вызов бэкенд сервера Express из React
Сначала перейдите в папку client/src и отредактируйте файл App.js , чтобы он выглядел следующим образом:
import React, < useEffect, useState >from 'react'; import logo from './logo.svg'; import './App.css'; function App() < const [state, setState] = useState(null); const callBackendAPI = async () => < const response = await fetch('/express_backend'); const body = await response.json(); if (response.status !== 200) < throw Error(body.message) >return body; >; // получение GET маршрута с сервера Express, который соответствует GET из server.js useEffect(() => < callBackendAPI() .then(res =>setState(res.express)) .catch(err => console.log(err)); >, []) return (
className="App-logo" alt="logo" /> Edit src/App.js and save to reload.
Learn React * вывод данных, полученных с сервера Express */> ); > export default App;
Внутри хука useEffect() вызывается функция callBackendAPI() . Эта функция будет получать данные с ранее созданного маршрута на сервере Express. При получении ответа от запроса fetch , значение res.express устанавливается в состояние state с помощью функции setState() .
Затем значение state выводится внутри элемента для отображения на странице.
Запуск приложения
Для запуска приложения перейдите в корневую директорию express-react-app
и выполните следующую команду:
$cd express-react-app $node server.js
После запуска файла server.js следующим шагом будет переход в веб-браузер по адресу http://localhost:5000/express_backend, и будет отображено следующее сообщение:
Успешный запуск бэкенда Express
Вышеуказанное демонстрирует, что наш сервер Express работает должным образом, и созданный нами маршрут GET функционирует, а также возможно получение этого маршрута с клиентской стороны.
Также обратите внимание, что путь URL совпадает с путем, который мы указали в нашем маршруте GET в файле server.js .
Затем перейдите в директорию client в терминале и выполните следующие команды:
$cd client $npm start
Вышеуказанные команды запустят React сервер разработки, который работает на порту 3000, и автоматически откроется в веб-браузере.
На экране будет отображено следующее сообщение:
Успешный запуск React App
Наконец, мы отобразили данные, полученные с маршрута GET в server.js , в нашем фронтенд React приложении, как было показано выше.
Если сервер Express отключен, сервер React всё равно будет продолжать работать. Однако связь с бэкендом будет потеряна, и ничего не будет отображаться.
Заключение
С помощью сервера Express можно сделать многое, например, осуществлять вызовы к базе данных. Однако в этом руководстве мы сосредоточились на том, как быстро подключить клиентское React приложение к серверу Express на стороне бэкенда.
Кодовые фрагменты и файлы, использованные в этом руководстве, можно найти в репозитории GitHub по этой ссылке.





