Home > front end >  React useParams not showing params at all, returns object with many values
React useParams not showing params at all, returns object with many values

Time:11-02

I am working on react and routing a few links in App.js, of which 2 have an :id parameter as seen below

import React from "react";
import "./App.css";
import { BrowserRouter as Route, Switch } from "react-router-dom";
import Home from "./Components/Home";
import NavBar from "./Components/NavBar";
import About from "./Components/About";
import Contact from "./Components/Contact";
import CatsList from "./Pages/CatsList";
import CatsUpdate from "./Pages/CatsUpdate";
import CatsCreate from "./Pages/CatsCreate";
import AuthCatShow from "./Pages/AuthCatShow";
import CatShow from "./Pages/CatShow";

function App() {
  return (
    <div className="App">
      <NavBar />
      <Switch>
          <Route exact path="/">
            <Home />
          </Route>
          <Route path="/about">
            <About />
          </Route>
          <Route path="/contact">
            <Contact />
          </Route>
          <Route path="/cats/:id">
            <AuthCatShow />
          </Route>
          <Route path="/cats/list">
            <CatsList />
          </Route>
          <Route path="/cats/new">
            <CatsCreate />
          </Route>
          <Route path="/cats/edit/:id">
            <CatsUpdate />
          </Route>
      </Switch>
    </div>
  );
}

export default App;

Note the components with cat/:id and cat/edit/:id requires the id params. I tried using use params in them, but it doesn't work. For example, for cats/:id, I did: let id = useParams(); and then I should be able to access the id like so: id.id (It was working a few days before!)

import axios from "axios";
import React, { useEffect, useState } from "react";
import { BrowserRouter as Link, useParams } from "react-router-dom";
import styled from "styled-components";

const LinkStyled = styled(Link)`
  text-decoration: none;
  color: black;
`;
const Img = styled.img`
  border-radius: 50%;
`;

function AuthCatShow() {
  let id = useParams();
  console.log(id);
  // For the cat data
  const [cat, setCat] = useState();
  const [toggle, setToggle] = useState(false);
  // handle function for adding comment
  const handleComment = (event) => {
    event.preventDefault();
    setToggle(!toggle);
    let text = event.target[0].value;
    let cat_id = id.id;
    let user_id = id.id;
    let email = id.id;

    const payload = { text, cat_id, user_id, email };
    axios
      .post(`http://localhost:3000/api/cats/${id.id}/newcomment`, payload)
      .then((res) => {
        window.alert(`Comment added!`);
      });
  };

  // handle function for updating comment
  const updateComment = async (id) => {
    setToggle(!toggle);
    let updateCommentText = prompt("Update the comment:");

    await axios
      .put(`http://localhost:3000/api/comments/${id}`, {
        text: updateCommentText,
      })
      .then((res) => {
        window.alert(`Comment updated!`);
      });
  };

  // handle function for deleting comment
  const deleteComment = (id) => {
    setToggle(!toggle);
    axios.delete(`http://localhost:3000/api/comments/${id}`);
  };

  // useeffect to get the cats data
  useEffect(() => {
    async function getCatData() {
      await axios.get(`http://localhost:3000/api/cats/${id.id}`).then((cat) => {
        setCat(cat.data.data);
      });
    }
    getCatData();
  }, [updateComment]);

  return (
    <>
      <div>
        <h1>{cat?.name}</h1>
        <Img src={cat?.image} alt={cat?.name} width="400px" height="400px" />
        <p>Description: {cat?.description}</p>
        <p>Gender: {cat?.gender}</p>
        <p>Adoptable: {cat?.adoptable}</p>
        <p>Cage: {cat?.cage}</p>
        <button>
          <LinkStyled to={`/cats/list`}> Back </LinkStyled>
        </button>
      </div>
      <div>
        <h3>Comments</h3>
        {cat?.comments?.map((element) => {
          return (
            <>
              <p key={element._id}>
                <p>
                  {element.text}
                  <button onClick={() => updateComment(element._id)}>
                    &#9998;
                  </button>
                  <button onClick={() => deleteComment(element._id)}>
                    &#128465;
                  </button>
                </p>
                <br />
                <p>Posted by: {element.email}</p>
              </p>
            </>
          );
        })}
        <form onSubmit={handleComment}>
          <input type="text" minLength="3" />
          <button>Add comment</button>
        </form>
      </div>
    </>
  );
}

export default AuthCatShow;

However, now, id.id doesn't work. For reference, when I console.log id, I get an object with many properties inside like this: enter image description here

I am really confused. Why is this the case? It was working a few days ago, and it was an object with just 1 property inside, allowing me to use "id.id" in my code. Any help would be appreciated!

CodePudding user response:

You can't use BrowserRouter as Route inside Switch . BrowserRouter has to be used outside of Switch . It should be like this .

import { BrowserRouter as Router, Route, Switch } from "react-router-dom";

function App() {
  return (
    <div className="App">
      <Router>
        <Switch>
          <Route path="/cats/:id">
            <AuthCatShow />
          </Route>
        </Switch>
      </Router>
    </div>
  );
}

export default App;

Try to use like this. It may work.

CodePudding user response:

Honestly I don't really know what happened but thank you for all your comments! There was some routing issue and I didn't change anything in the component, I simply edited the routes in App.js like so:

import React from "react";
import "./App.css";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import Home from "./Components/Home";
import NavBar from "./Components/NavBar";
import About from "./Components/About";
import Contact from "./Components/Contact";
import CatsList from "./Pages/CatsList";
import CatsUpdate from "./Pages/CatsUpdate";
import CatsCreate from "./Pages/CatsCreate";
import AuthCatShow from "./Pages/AuthCatShow";
import CatShow from "./Pages/CatShow";

function App() {
  return (
    <div className="App">
      <Router>
        <NavBar />
        <Route exact path="/">
          <Home />
        </Route>
        <Route path="/about">
          <About />
        </Route>
        <Route path="/contact">
          <Contact />
        </Route>
        <Switch>
          <Route path="/cats/list">
            <CatsList />
          </Route>
          <Route path="/cats/new">
            <CatsCreate />
          </Route>
          <Route path="/cats/edit/:id">
            <CatsUpdate />
          </Route>
          <Route path="/cats/:id">
            <AuthCatShow />
          </Route>
        </Switch>
      </Router>
    </div>
  );
}

export default App;

And now the useParams work!

  • Related