Сервер Node.js перезаписал весь DOM с помощью React.JS - PullRequest
0 голосов
/ 26 сентября 2018

Что я пытаюсь сделать: я пытаюсь попрактиковаться в структуре MERN, поэтому я хотел настроить сервер node.js и сначала отреагировать на интерфейс.

Однако произошло то, что когдасервер запускается, весь DOM перезаписывается, почему это так?

server.js - это простой node.js

const express = require('express');
const app = express();

// console.log that your server is up and running
app.listen(3000, () => console.log(`Listening on port 3000`));

// create a GET route
app.get('/test', (req, res) => {
  res.send({ express: 'I MADE IT' });
});

React.js - мой интерфейс:

import React from 'react';
import logo from './img/nav-logo.png';
import Product1 from './img/manage.png';
import Product2 from './img/deliver.png';
import Product3 from './img/market.png';
import Service from './service.js'
import './App.css';
import 'bootstrap/dist/css/bootstrap.min.css';

class App extends React.Component {
  constructor(props){
    super(props)

    this.state={
      items: [{
          desc:"Manage",
          price: 5000,
          purchased: false,
        },
        {
          desc:"Deliver",
          price: 2000,
          purchased: false,
        },
        {
          desc:"Market",
          price: 4000,
          purchased: false,
        }
      ],
      data:null,
    }
  }

  componentDidMount() {
    console.log("here")
    this.callApi()
      .then(res => this.setState({ data: res.express }))
      .catch(err => console.log(err));
  }

  callApi = async () => {
    const response = await fetch('/test');
    const body = await response.json();

    if (response.status !== 200) throw Error(body.message);

    return body;
  };

  handleClick(desc){
    const newItems = this.state.items.slice()
    this.printItems(newItems)
    for(var item of newItems){
      if(item.desc === desc){
        item.purchased = !item.purchased
      }
    }
    this.printItems(newItems)

    this.setState({
      items: newItems
    })
  }

  printItems(items){
    console.log(items[0].purchased + "  " + items[1].purchased + " " + items[2].purchased)
  }

  render()  {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h1 className="App-title">Welcome to Shopping Center</h1>
        </header>
      <div>
        <div>
          {this.state.data}   //<------------trying to render the data here
        </div>
        <Service url={Product1} desc="Manage" alt="MA" purchased={this.state.items[0].purchased} thisClick={ (desc) => this.handleClick("Manage")} />
        <Service url={Product2} desc="Deliver" alt="DE" purchased={this.state.items[1].purchased} thisClick={ (desc) => this.handleClick("Deliver")}/>
        <Service url={Product3} desc="Market" alt="MR" purchased={this.state.items[2].purchased} thisClick={ (desc) => this.handleClick("Market")}/>
      </div>
      </div>
    );
  }
}

export default App;

Когда мой файл node.js не запущен, я могу нормально отреагироватьТем не менее, однажды я делаю npm server.js.localhost: 3000 больше не будет работать.Итак, я обработал localhost:3000/test, и весь HTML стал строкой "{express: 'I MADE IT'}"

My index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

Я хочу сделать сообщениекак часть моего обычного React DOM, но каким-то образом сервер узла перезаписал весь мой интерфейс.

Кроме того, я получил сообщение об ошибке в состоянии консоли следующее:

SyntaxError: Unexpected token < in JSON at position 0
    at App._callee$ (App.js:42)
    at tryCatch (runtime.js:62)
    at Generator.invoke [as _invoke] (runtime.js:296)
    at Generator.prototype.(:3000/anonymous function) [as next] (http://localhost:3000/static/js/bundle.js:31252:21)
    at step (App.css?9a66:26)
    at App.css?9a66:26

Строкакода, который я нашел, это componentDidMount() метод

Мой файл package.json:

{
  "name": "my-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "bootstrap": "^4.1.3",
    "express": "^4.16.3",
    "react": "^16.5.2",
    "react-dom": "^16.5.2",
    "react-scripts": "1.1.5",
    "reactstrap": "^6.4.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "proxy": "http://localhost:3001"
}

1 Ответ

0 голосов
/ 26 сентября 2018

Для development , если вы используете приложение create-реагировать для приложения React, вы можете использовать proxy для разработки для запуска Express и React на отдельных портах.Все fetch() запросы будут перенаправлены на указанный путь / порт прокси в package.json.Это позволит вам использовать преимущества инструментов разработки для каждой платформы.

  1. Измените порт сервера Express на любой другой, кроме 3000.Например, app.listen(3001, () => console.log('Listening on port 3001')); Это так, что create-реагировать-приложение может работать на 3000, а Express может работать на 3001.
  2. Добавлена ​​следующая строка в package.json приложения React для включения прокси,"proxy": "http://localhost:3001".Запрос выборки на /api/test будет перенаправлен на http://localhost:3001/api/test.

Для production , если вы хотите, чтобы оба приложения работали на одном и том же порту:

  1. Настройка статической загрузки ресурсов для сервера с использованием метода static () .
  2. Добавлена ​​логика для сервера, чтобы перенаправлять все запросы, которые не соответствуют вашим путям "API", взагрузите index.html производственного приложения npm run build React, используя sendFile () .Это позволит использовать маршрутизацию в приложении React.

Вот как это может выглядеть на базовом уровне, с папкой create-реагировать-приложение build, созданной из команды npm run buildпомещено в путь /public/build:

app.use(express.static(path.join(__dirname, 'public', 'build')));

// API route
app.get('/api/test', (req, res) => {
  res.send({ express: 'I MADE IT' });
});

// catch-all route
app.use('*', function (request, response) {
  response.sendFile(path.join(__dirname, 'public', 'build', 'index.html'));
});

Реакция fetch():

// ...
const response = await fetch('/api/test'); // this matches the path specified on server, before the catch all route
const body = await response.json();
// ...

Проверьте этот ответ , поскольку это была похожая проблема.

Обновление: - Действия по созданию простой среды разработки Express + React:

  1. Создание приложения Express с использованием express-generator .Запустите команду npx express-generator react-express
  2. Перейдите в созданный проект.Команда запуска cd react-express.
  3. Команда запуска npm install.Затем удалите каталог public.
  4. Создайте приложение React, используя create-react-app.Запустите команду npx create-react-app public.
  5. Установить concurrently.Запустите команду npm install concurrently --save-dev.
  6. Редактировать app.js в основании проекта, созданного express-generator.Добавьте следующие строки, начиная со строки 25. Это означает, что конечная точка и точка доступа будут отображаться в /api/test и предоставят «универсальный» маршрут для загрузки index.html, сгенерированный npm run build.

```

app.get('/api/test', (req, res) => {
  res.send({ express: 'I MADE IT' });
});

app.use('*', function (request, response) {
  response.sendFile(path.join(__dirname, 'public', 'build', 'index.html'));
});

` ``

Редактировать /bin/www строку 15, чтобы изменить порт с 3000 на 3001. var port = normalizePort(process.env.PORT || '3001'); Редактировать package.json, созданный create-реагировать-приложение в /build/package.json.Добавьте следующую строку "proxy": "http://localhost:3001". На базе package.json, расположенной в корне проекта, созданного express-generator, добавьте следующую строку в srcipts: "dev": "concurrently \"node ./bin/www\" \"cd public && npm start\"" Запустите команду npm run dev из базы проекта.Это загрузит сервер (Express) и клиент (React) и вызовет прокси, в этом примере /api/test на порт 3000 будет направлен на порт сервера, работающий на 3001.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...