11

I've created a React application which uses fetch() to the route file on componentDidMount to build out data in the rendered component.

This works great, but the React component is static when the data in the MySQL database is updated.

How do I update my React component with any changes when the data in the MySQL database is changed? Please see an example of my code below.

React File - react.js

class myComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            data: []
        }
    }

    // componentDidMount - When the component is mounted.
    componentDidMount() {

        // Retrieve project data from the database.
        fetch('/retrieve-data', {
            credentials: 'include'
        })
        .then((response) => {
            if (response.ok) {
                return response.json();
            } else {
                console.log('Error with session response');
            }
        })
        .then((result) => {

            // Set the state of data.
            this.setState({
                data: data
            })
        })
        .catch((error) => {
            console.log('Error: ', error);
        });
    }

    render() {
        return (
            <div>

                {/* Loop Data Array */}
                {this.state.data.map((thisData, k) => (
                    <div key={k}>
                        {thisData.field1}
                    </div>
                ))}

            </div>
        )
    }
}

Route File - retrieve-data.js

var express = require('express');
var router = express.Router();
var mysql = require('mysql');

var connection = mysql.createConnection({
    host: myHost,
    user: myUser,
    password: myPassword,
    database: myDatabase
})

router.get('/', function(req, res, next) {

    // Select data from the database.
    connection.query("SELECT * FROM database_table", function (error, resultData, fields) {

        // Send the result message back to the React application.
        res.send({resultData});
    });
});

module.exports = router;

The data is updated by a Webhook on a separate route file, so this could be where I would want the server to tell React that it needs to update, but only if the change was relative to the data the individual client is seeing.

Apologies for this question, I am very new to React. Thank you!

3
  • 3
    You either need to send a push notification from the server, which the client is listening for, or set up an interval on the client that pings the server for occasional updates, or do another fetch after you POST to the server, or just append the POSTed data directly to state, which should be identical to what the refresh would do. Commented Dec 20, 2018 at 15:25
  • Thank you. As the data will be updated by a Webhook, how can I tell the Webhook route file to change the state in React? I'm thinking of the third option you have mentioned to do another fetch. So I guess at the point that the Webhook is received by the Webhook route file is when I would need to tell the client to fetch once more. Thanks! Commented Dec 20, 2018 at 15:31
  • 2
    I don't much any experience with webhooks, but the nuclear option here would be to do a window.location.href='/myRoute' which would force a full refresh of the page, and would induce your componentDidMount fetch to fire. That said, Im sure someone with experience with webhooks could give you better insight. Commented Dec 20, 2018 at 15:41

3 Answers 3

7

https://www.npmjs.com/package/socket.io

You could use socket.io to relay the changes.

Non-conventional approach would be to setup a front-end loop that checks every so often for changes and updates the DOM, but that can get resource intensive when you have many users on the website.

Sign up to request clarification or add additional context in comments.

Comments

7

You could look into using web sockets for pushing updates to your front-end.

Basic flow would be:

  1. Broadcast message from your server to React client when data changes
  2. Listen for the ‘dataChanged’ event in React, and update React’s state accordingly when this is received

Comments

5

While you can use Web Sockets, as suggested by @jonnyg, and in fact that is the more performant approach, that requires being familiar with Web Sockets and will require changes on the server.

A simpler approach you can implement on the client side would be to implement a polling system, whereby you basically keep "asking" the server for the data every x seconds and see if it changed.

You can do this by creating a setInterval timer which will make your network request every x seconds.

5 Comments

The changes won't be huge, for example, a field will change from 'Test1' to 'Test2'. So I would only really need to poll the server every 10 seconds roughly. How much weight would this add to client performance? Thanks for your answer.
While I can't give you an exact answer, if it's a small amount of data and only every 10 seconds you should be totally fine. I implemented something like this recently hitting the server every 2 seconds to get the progress of something and there didn't seem to be any performance hit.
I built a website that did this and I thought it would be me and a few friends using it, requesting new API data every 5 seconds and updating the state. Ended up being about 40 concurrent users at a time and the MongoDB would topple over daily. Be cautious with this route, I would only apply it within a closed environment where you know you will only have a few users spending limited time on the page that uses it.
Thanks for your help Nick. @Dadsquatch - the app will need to scale, so I'm concerned at this now and will take a look at sockets firstly.
yup that does sound like the route you'd want to take. Good luck

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.