React - TypeError: Cannot read properties of undefined (reading 'params')?

Viewed 250

I'm trying to access and console.log the the id params but keep getting an error saying that theyre undefined. Why is that? The page loads perfectly and I can see the users id in the url.But when I go to console.log it the webpage crashes and it says Cannot read properties of undefined (reading 'params')

This is other profile where I try and recieve the id from the param

     export default class OtherProfile extends Component {
  constructor(props) {
    super(props);
    console.log(this.props.match.params.id)

    this.state = {
      redirect: null,
      userDetails: [],
      activeItem: 'favourites'
    };
  }

  componentDidMount() {
    // const id = this.props.params.user._id;
    // console.log(id)
    // Axios.post('http://localhost:8080/api/user/getUserDetails')
    // .then(response => {
    //     if (response.data.success) {
    //         console.log('Users Details', response.data)
    //         setFavouriteList(response.data.films)
    //     } else {
    //         alert('Error')
    //     }
    // })
  }

  handleItemClick = (e, { name }) => this.setState({ activeItem: name })

  onClick = (e) => {
    this.props.history.push("/profile/edit");
  }


  renderSwitch(activeItem) {
    switch (activeItem) {
      case 'reviews':
        return <SentimentComponent />;
      case 'films':
        return <Films />;
      case 'portfolio':
        return <Portfolio />;
      case 'favourites':
        return <FavouriteContainer />;
      case 'futurefilms':
        return <FutureFilms />;
    }
  }


  render() {
    if (this.state.redirect) {
      return <Redirect to={this.state.redirect} />
    }
    const { activeItem } = this.state;

    return (
      <div className="container">
        {(this.state.userReady) ?
          <div>
            <br></br>
            <Avatar size={180} icon={<UserOutlined />}/>
            <p>
              <strong>Email:</strong>{" "}
              {/* {currentUser.email} */}
            </p>
            <strong>Username: </strong>
            {/* {currentUser.username} */}
            <p>
              <button onClick={this.onClick}> EDIT </button>
              {/* <strong>Phone Number: </strong>
              {currentUser.phoneNo} */}
            </p>
          </div> : null}
        <Menu>
          <Dropdown
            item text='Films'
            name='films'>
            <Dropdown.Menu>
            <Dropdown.Item
                name="favourites"
                active={activeItem === 'favourites'}
                onClick={this.handleItemClick}>
                Favourites
              </Dropdown.Item>
              <Dropdown.Item
                name="futurefilms"
                active={activeItem === 'futurefilms'}
                onClick={this.handleItemClick}>
                Future Films
              </Dropdown.Item>
            </Dropdown.Menu>
          </Dropdown>
          <Menu.Item
            name='reviews'
            active={activeItem === 'reviews'}
            onClick={this.handleItemClick}
          />
          <Menu.Item
            name='portfolio'
            active={activeItem === 'portfolio'}
            onClick={this.handleItemClick}
          />
          <Menu.Item
            name='campaign'
            active={activeItem === 'campaign'}
            onClick={this.handleItemClick}
          />
        </Menu>
        {this.renderSwitch(activeItem)}
      </div>
    );
  }
}

This is where I send my id

const UserListComponent = (props) => {
  const [loading, setLoading] = useState(true);
  const [userList, setUserList] = useState([]);
  const { username } = useParams();

  const history = useHistory();

  useEffect(() => {
    Axios.get(`http://localhost:8080/api/search?username=${username}`, {
      headers: authHeader(),
    })
      .then(({ data }) => {
        console.log(data.users);
        setUserList(data.users);
        setTimeout(() => setLoading(false), 500);
      })
      .catch((err) => {
        console.log(err);
        setLoading(false);
      });
  }, []);

  return (
    <UserListContainer
      onClick={() => {
        //history.push(`/films/${props.movieList.movie.id}`)
      }}
    >
      {loading && <div>Loading...</div>}
      {!loading &&
        userList.map((user, i) => (
          <Link key={i} to={`/user/${user._id}`}>
            {user.username}
          </Link>
        ))}
      {!loading && userList.length === 0 && (
        <div>No users exist with the paramters!</div>
      )}
    </UserListContainer>
  );
};

export default UserListComponent;

This where I get the user of the profile

import React, { useEffect, useState } from 'react';
import { Link, useParams } from 'react-router-dom';
import styled from 'styled-components';
import { useHistory } from 'react-router-dom'; // services
import authHeader from '../services/auth-header';
import Axios from 'axios';
import OtherProfile from './profile/OtherProfile'

const UserListContainer = styled.div`
  display: flex;
  flex-direction: column;

  padding: 30px;
  gap: 25px;
  justify-content: center;
  align-items: center;
`;

const MemberUser = (props) => {
  const [loading, setLoading] = useState(true);
  const [user, setUser] = useState(null);
  const { id } = useParams();
  const history = useHistory();

  useEffect(() => {
    Axios.get(`http://localhost:8080/api/user/?id=${id}`, {
      headers: authHeader(),
    })
      .then(({ data }) => {
        console.log(data);
        setUser(data);
        setTimeout(() => setLoading(false), 500);
      })
      .catch((err) => {
        console.log(err);
        setLoading(false);
      });
  }, []);

  return (
    <UserListContainer
      onClick={() => {
        //history.push(`/films/${props.movieList.movie.id}`)
      }}
    >
      {loading && <div>Loading...</div>}
      {!loading && user && (
      <OtherProfile/>
      )}
      {!loading && !user && <div>No users exist with that id!</div>}
    </UserListContainer>
  );
};

export default MemberUser;
1 Answers
{!loading && user && (
  <OtherProfile/>
)}

You're not passing any props into this element, so this.props.match is going to be undefined. I don't know exactly what you want your match logic to do, but it may be something like this:

const MemberUser = (props) => {
  const [loading, setLoading] = useState(true);
  const [user, setUser] = useState(null);
  const { id } = useParams();
  const history = useHistory();
  const match = useRouteMatch("/user/:id"); // <---- added

  // ...

  {!loading && user && (
    <OtherProfile match={match} />
  )}

  // ...
}
Related