Kevin Kevin - 2 months ago 24
Node.js Question

Send data to a route using Express JS when you are serving a static file for React-Router

What i'm trying to achieve: Routes made with Express JS that can fetch data (for example from: https://tmi.twitch.tv/group/user/instak/chatters), which send it via React Router to my correct route and make React wait until the data is fetched so I can use that data to work with client-side.

What i've tried

server.js

'use strict';
const express = require('express');
const app = express();
const path = require('path');

app.use(express.static(path.resolve(__dirname, '..', 'instakbot-client')));

// Always return the main index.html, so react-router render the route in the client
app.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, '..', 'instakbot-client', 'index.html'));
});

app.get('/home', (req, res) => {
res.send("I'm just testing to see if this works");
});

const PORT = process.env.PORT || 8000;

app.listen(PORT, () => {
console.log(`App listening on port ${PORT}!`);
});


script.js

import ReactDOM from 'react-dom';
import React from 'react';
import Router from './routers/';

const init = () => {

ReactDOM.render(
<Router/>,
document.querySelector('.react-app')
);
};

init();


index.html

<!DOCTYPE html>
<html lang="en">

<head>
<title>Frafbot</title>
<link rel="stylesheet" type="text/css" href="css/style.css">
<base href="/" />
</head>

<body>
<div class="react-app">
</div>
<script src="js/script.js"></script>
</body>
</html>


app.jsx

import React from 'react';

export default ({children}) => {
return (
<div className='container'>

<main>
{children}
</main>

</div>
);
};


routers/index.js

import React from 'react';
import {Router, Route, IndexRedirect, useRouterHistory} from 'react-router';
import {createHistory} from 'history';

import {App, Overview, Users} from '../pages';

export default () => (

<Router history={useRouterHistory(createHistory)({basename: ''})}>

<Route path="/" component={App}>
<IndexRedirect to="home"/>
<Route path="home" component={Overview} />
<Route path="users" component={Users} />
</Route>

</Router>

);


overview.jsx

import React from 'react';

export default () => {
return (
<div>
<h2>Elaba</h2>
<div>I am the overview page</div>
</div>
);
};


users.jsx

import React, {Component} from 'react';

export default class Users extends Component{
constructor(props, context){
super(props, context);
}

render(){
return (
<div>
<p>I am the Users component</p>
</div>
);
}
}


Conclusion: As you can see in server.js I have a get route for '/home', which won't work because there is a get route for '' to get the static file. But if I put that route ABOVE the '' route I only get '/home' res... What I want to find is a way to add data by adding a route... You can kind of see it as a route that gets all the default values but can also be overwritten or get additional values...

Is there any possibility I can fetch the data from https://tmi.twitch.tv/group/user/instak/chatters and get the data in my React component to work with?

Thanks in advance for helping me, I've tried a lot to get this working already...

Answer

I would declare the routes like:

// Declare API routes before '*'
// Note this route has 'api' prefix
app.get('/api/home', (req, res) => {
  res.json({ message: "I'm just testing to see if this works" });
});

app.get('*', (req, res) => {
  res.sendFile(path.resolve(__dirname, '..', 'instakbot-client', 'index.html'));
});

And then on the React client app:

class Home extends React.Component {
  state = { message: null }
  componentDidMount() {
     fetch('/api/home') // fetch from Express.js server
      .then(response => response.json())
      .then(result => this.setState({ message: result.message }));
  }

  render() {
    const { message } = this.state;
    // ...
  }
}

export default () => (

  <Router history={useRouterHistory(createHistory)({basename: ''})}>

    <Route path="/" component={App}>
      <IndexRoute component={Home} />
      <Route path="home" component={Overview} />
      <Route path="users" component={Users} />
    </Route>

  </Router>

);

Related question: https://github.com/mrpatiwi/routed-react/issues/1

Comments