Cannot read properties of undefined (reading 'search'). My location returning undefined and this is react-router-dom v6

Viewed 20

There were some major changes in v6 and I seem unable to access the name and room parameters. Chat page utilizes a few components that I did not include. The error is being thrown in Chat.jsx and I'm not sure how to properly instantiate useLocation(). withRouter has been removed as well. My app is wrapped in Router. I know it's also possible to use getParams.

Join.jsx

import { useState } from "react";

import { Link } from "react-router-dom";

const Join = () => {
  
  const [name, setName] = useState("");
    const [room, setRoom] = useState("");

  return (
    <div className="joinOuterContainer">
        <div id="form-area">
                    <h1 className="heading">Join</h1>
                    <p className="join-phone">Sign in to join a room!</p>

                    <div>
            <input type="text" className="joinInput" onChange={e => {setName(e.target.value)}} spellCheck="false" required />
            <label>Name</label>
          </div>

          <div>
            <input type="text" className="joinInput" onChange={e => {setRoom(e.target.value)}} spellCheck="false" required />
            <label>Room</label>
          </div>

          <Link onClick={e => (!name || !room ? e.preventDefault() : null)}
                        to={`./chat?name=${name}&room=${room}`}>
                        <button className="button" type="submit">
                            Sign In
                        </button>
                    </Link>

          </div>
    </div>
  );
};

Chat.jsx

import { useState, useEffect } from "react";
import queryString from "query-string"
import io from "socket.io-client"



import RowUsers from "./RowUsers"
import RowContent from "./RowContent"




let socket;


function Chat({ location }) {

    console.log(location)
    const [name, setName] = useState("")
    const [room, setRoom] = useState("")
    const [users, setUsers] = useState([])
    const [message, setMessage] = useState("")
    const [messages, setMessages] = useState([])

    const END_POINT = "http://localhost:3939"

    useEffect(() => {
        console.log('location inside effect:',location)
        let {name, room} = queryString.parse(location.search)
        console.log(name, room, location)
        socket = io(END_POINT)
        console.log(name, room)
        setName(name)
        setRoom(room)

        socket.emit("join", { name, room })

        return () => {
            socket.emit("disconnect")
            socket.off()
        }
    }, [END_POINT, location, location.search])

    useEffect(() => {
        socket.on("message", message => {
            setMessages("message", message => {
                setMessages(messages => [...messages, message])
            })

            socket.on("roomData", ({ users }) => {
                setUsers(users)
            })
        })
    }, [])

    const sendMessage = event => {
        event.preventDefault()
        if(message) {
            socket.emit("sendMessage", message)
            setMessage("")
        }
    }
    
    return (
        <div className="main-chat-container">
            <div className="chat-container">
                <RowUsers room={room} users={users} />
                <RowContent
                    message={message}
                    setMessage={setMessage}
                    sendMessage={sendMessage}
                    messages={messages}
                    name={name}
                    room={room}
                />
            </div>
        </div>
    )

}

export default Chat

App.js

import logo from './logo.svg';
import './App.css';
import * as React from 'react';

function App() {

  return (
    
    <div className="App">
      
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
      </header>
     
     <div>
     </div>
      
    </div>
  );
}

export default App;

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

import { BrowserRouter as Router,Routes, Route } from "react-router-dom";
import Join from './Join';
import Chat from './Chat/Chat'

const root = ReactDOM.createRoot(document.getElementById('root'));

root.render(
  <React.StrictMode>
    
    <Router> 
      <App />
      <Routes>
        <Route path="/" exact element={<Join/>} />
        <Route path="/chat" element={<Chat/>} />
      </Routes>

      </Router>
   
  </React.StrictMode>
);
1 Answers

just change your index.js like this :

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

import { BrowserRouter as Router,Routes, Route } from "react-router-dom";
import Join from './Join';
import Chat from './Chat/Chat'

const root = ReactDOM.createRoot(document.getElementById('root'));
const location = useLocation();

root.render(
  <React.StrictMode>
    
    <Router> 
      <App />
      <Routes>
        <Route path="/" exact element={<Join/>} />
        <Route path="/chat" element={<Chat location={location} />} />
      </Routes>

      </Router>
   
  </React.StrictMode>
);

hope this answer helps you!

Related