Need help replacing withRouter and History in React for Social Media Project

Viewed 22

Need help replacing withRouter and History in React in my code below. This used to work for React v5 but I want to find a way to make this work in v6. I am not sure how to go about it so Please help! Here is my CreateProfile.js for my social media project:

import React, { Fragment, useState } from 'react';
import { Link, withRouter } from 'react-router-dom';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { createProfile } from '../../actions/profile';

const CreateProfile = ({ createProfile, history }) => {
  const [formData, setFormData] = useState({
    company: '',
    website: '',
    location: '',
    status: '',
    skills: '',
    githubusername: '',
    bio: '',
    twitter: '',
    facebook: '',
    linkedin: '',
    youtube: '',
    instagram: ''
  });

  const [displaySocialInputs, toggleSocialInputs] = useState(false);

  const {
    company,
    website,
    location,
    status,
    skills,
    githubusername,
    bio,
    twitter,
    facebook,
    linkedin,
    youtube,
    instagram
  } = formData;

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

  const onSubmit = e => {
    e.preventDefault();
    createProfile(formData, history);

  }

  


  return (
    <Fragment>      
      <h1 className="large text-primary">
    Create Your Profile
    </h1>
  <p className="lead">
    <i className="fas fa-user"></i> Let's get some information to make your
    profile stand out
  </p>
  <small>* = required field</small>
  <form className="form" onSubmit={e => onSubmit(e)}>
    <div className="form-group">
      <select name="status" value={status} onChange={e => onChange(e)}>
        <option value="0">* Select Professional Status</option>
        <option value="Developer">Developer</option>
        <option value="Junior Developer">Junior Developer</option>
        <option value="Senior Developer">Senior Developer</option>
        <option value="Manager">Manager</option>
        <option value="Student or Learning">Student or Learning</option>
        <option value="Instructor">Instructor or Teacher</option>
        <option value="Intern">Intern</option>
        <option value="Other">Other</option>
      </select>
      <small className="form-text"
        >Give us an idea of where you are at in your career</small
      >
    </div>
    <div className="form-group">
      <input type="text" placeholder="Company" name="company" value={company} onChange={e => onChange(e)} />
      <small className="form-text"
        >Could be your own company or one you work for</small
      >
    </div>
    <div className="form-group">
      <input type="text" placeholder="Website" name="website" value={website} onChange={e => onChange(e)} />
      <small className="form-text"
        >Could be your own or a company website</small
      >
    </div>
    <div className="form-group">
      <input type="text" placeholder="Location" name="location" value={location} onChange={e => onChange(e)}/>
      <small className="form-text"
        >City & state suggested (eg. Boston, MA)</small
      >
    </div>
    <div className="form-group">
      <input type="text" placeholder="* Skills" name="skills" value={skills} onChange={e => onChange(e)} />
      <small className="form-text"
        >Please use comma separated values (eg.
        HTML,CSS,JavaScript,PHP)</small
      >
    </div>
    <div className="form-group">
      <input
        type="text"
        placeholder="Github Username"
        name="githubusername"
        value={githubusername} onChange={e => onChange(e)}
      />
      <small className="form-text"
        >If you want your latest repos and a Github link, include your
        username</small
      >
    </div>
    <div className="form-group">
      <textarea placeholder="A short bio of yourself" name="bio" value={bio} onChange={e => onChange(e)}></textarea>
      <small className="form-text">Tell us a little about yourself</small>
    </div>

    <div className="my-2">
      <button onClick={() => toggleSocialInputs(!displaySocialInputs)} type="button" className="btn btn-light">
        Add Social Network Links
      </button>
      <span>Optional</span>
    </div>

    {displaySocialInputs && <Fragment>
      <div className="form-group social-input">
      <i className="fab fa-twitter fa-2x"></i>
      <input type="text" placeholder="Twitter URL" name="twitter" value={twitter} onChange={e => onChange(e)} />
    </div>

    <div className="form-group social-input">
      <i className="fab fa-facebook fa-2x"></i>
      <input type="text" placeholder="Facebook URL" name="facebook" value={facebook} onChange={e => onChange(e)} />
    </div>

    <div className="form-group social-input">
      <i className="fab fa-youtube fa-2x"></i>
      <input type="text" placeholder="YouTube URL" name="youtube" value={youtube} onChange={e => onChange(e)} />
    </div>

    <div className="form-group social-input">
      <i className="fab fa-linkedin fa-2x"></i>
      <input type="text" placeholder="Linkedin URL" name="linkedin" value={linkedin} onChange={e => onChange(e)} />
    </div>

    <div className="form-group social-input">
      <i className="fab fa-instagram fa-2x"></i>
      <input type="text" placeholder="Instagram URL" name="instagram" value={instagram} onChange={e => onChange(e)} />
    </div>
    </Fragment>}

    
    <input type="submit" className="btn btn-primary my-1" />
    <a className="btn btn-light my-1" href="dashboard.html">Go Back</a>
  </form>
  </Fragment>
  );
};

CreateProfile.propTypes = {
  createProfile: PropTypes.func.isRequired
};


export default connect(null, { createProfile })(withRouter(CreateProfile));

and here is my profile.js in my actions folder:

import axios from 'axios';
import { setAlert } from './alert';

import {
    GET_PROFILE,
    PROFILE_ERROR
} from './types';

// Get current users profile
export const getCurrentProfile = () => async dispatch => {
    try {
      const res = await axios.get('/api/profile/me');

      dispatch({
        type: GET_PROFILE,
        payload: res.data
      });
    } catch (err) {
      dispatch({
        type: PROFILE_ERROR,
        payload: { msg: err.response.statusText, status: err.response.status}
      });
    }
};

// Create or update profile
export const createProfile = (formData, history, edit = false) => async dispatch => {
  try {
    const config = {
      headers: {
        'Contet-Type': 'application/json'
      }
    }

    const res = await axios.post('/api/profile', formData, config);

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

    dispatch(setAlert(edit ? 'Profile Updated' : 'Profile Created'));

    if(!edit) {
      history.push('/dashboard');
    }
  } catch (err) {
    const errors = err.response.data.errors;

    if (errors) {
      errors.forEach(error => dispatch(setAlert(error.msg, 'danger')));
    }

    dispatch({
      type: PROFILE_ERROR,
      payload: { msg: err.response.statusText, status: err.response.status}
    });
  }
}
1 Answers

In react-router-dom@6 there are no route props and because of this there is no need for the withRouter Higher Order Component, these were all removed.

In RRDv5 you could also access the history object via the useHistory hook. The useHistory hook is replaced by the useNavigate hook in RRDv6. See the migration guide for more detail here.

Import and use the useNavigate hook from react-router-dom.

...
import { Link, useNavigate } from 'react-router-dom';
...

const CreateProfile = ({ createProfile }) => {
  const navigate = useNavigate(); // <-- access navigate function

  ...

  const onSubmit = e => {
    e.preventDefault();
    createProfile(formData, navigate); // <-- pass navigate function
  }

  return (
    ...
  );
};

CreateProfile.propTypes = {
  createProfile: PropTypes.func.isRequired
};

export default connect(null, { createProfile })(CreateProfile);

...

// Create or update profile
export const createProfile = (formData, navigate, edit = false) => 
  async dispatch => {
    try {
      ...

      if (!edit) {
        navigate('/dashboard'); // <-- invoke navigate function for PUSH
      }
    } catch (err) {
      ...
    }
  };
Related