Help in fetching data from Database in component using React Hooks

Hello guys, so I’m basically pretty much new to the MERN stack and right now I’m trying to build an administration dashboard which will have CRUD functionalities.

As far as today, I currently now how to add, delete & view entries. The problem that I’m having right now comes when fetching data according to specific _id.

Let’s put it this way, I’m using a route like this:
<PrivateRoute exact path="/admin/pages/update/:id" component={PageUpdate} />

In order to be able to access to the specific _id, I have to use something called match as a prop, then I pass match.params.id as a paremeter inside the getPost function(we will talk more about it later on).

The PageUpdate component calls this document…which is the one I’m having troubles with:

import React, { useState, useEffect } from 'react';
import { Link, withRouter } from 'react-router-dom';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import Spinner from '../../layout/Spinner';
import { getPost, updatePage } from '../../../actions/admin/page';

const Update = ({ getPost, updatePage, pages: { page, loading }, match, history }) => {

  const [formData, setFormData] = useState({
    title: '',
    text: '',
  });

  useEffect(() => {
    getPost(match.params.id);
    setFormData({
      title: !page.title ? '' : page.title,
      text: !page.text ? '' : page.text
    });
    // eslint-disable-next-line
  }, [
      loading,
      // page,
      getPost,
      match.params.id
    ]);

  const {
    title,
    text
  } = formData;

  const onChange = e =>
    setFormData({ ...formData, [e.target.name]: e.target.value });

  const onSubmit = e => {
    e.preventDefault();
    updatePage(formData, history, true);
  };

  return loading || page === null ? (
    <Spinner />
  ) : (
      <section className="mb-3">
        <div className="container-fluid">
          <h1 className="border-bottom-dark pb-3 mb-3">Update Your Page</h1>
          <small>* = required field</small>
          <form className="form" onSubmit={e => onSubmit(e)}>
            <div className="form-group">
              <input
                type="text"
                placeholder="* Title"
                name="title"
                autoComplete="title"
                className="form-control"
                value={title}
                onChange={e => onChange(e)}
              />
              <small className="form-text">Could be your own nickname</small>
            </div>
            <div className="form-group">
              <textarea
                placeholder="Write here"
                name="text"
                autoComplete="text"
                className="form-control"
                value={text}
                onChange={e => onChange(e)}
              />
              <small className="form-text">So what are you up to?</small>
            </div>
            <div className="btn-group">
              <input type="submit" className="btn btn-primary my-1" />
              <Link className="btn btn-dark my-1" to="/admin/pages">Go Back</Link>
            </div>
          </form>
        </div>
      </section>
    );
};

Update.propTypes = {
  updatePage: PropTypes.func.isRequired,
  getPost: PropTypes.func.isRequired,
  pages: PropTypes.object.isRequired,
};

const mapStateToProps = state => ({
  pages: state.page
});

export default connect(
  mapStateToProps,
  { getPost, updatePage }
)(withRouter(Update));

Now the getPost function calls this route:

// Get post
export const getPost = id => async dispatch => {
  try {

    const res = await axios.get(`/api/admin/pages/${id}`);

    dispatch({
      type: GET_PAGE,
      payload: res.data
    });

  } catch (err) {
    dispatch({
      type: PAGE_ERROR,
      payload: { msg: err.response.statusText, status: err.response.status }
    });
  }
};

Which according to Postman is working fine!.

Do you guys have any idea why I’m unable to fetch data from the MongoDB database?.

Thanks in advance.

The remote call is asynchronous, in JavaScript a program doesn’t just stop to get the value when you fetch things, so it’s going to getPost but the values you set on the form data are going to be undefined; this is why callbacks/promises/async-await are used for async calls. React does absolutely nothing special* in this regard, exactly the same rules apply as with any other JS program.

* edit: until the suspense for data loading API drops sometime later this year at which point there will be a a partial solution to what you’re doing, though it won’t involve hooks