'The above error occurred in the <BrowserRouter> component, Invalid hook call

I'm trying to use a react-router, after using the library some problems begin, I've already tried to write different code, I found it ready-made on the Internet, but still something is wrong (even reset Windows). This code is taken from the official react-router documentation, did everything as written (https://reactrouter.com/docs/en/v6/getting-started/installation) Here is the errors:

Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. >This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem. printWarning @ react.development.js:207

Uncaught TypeError: Cannot read properties of null (reading 'useRef')

at useRef (react.development.js:1628:1)

at BrowserRouter (index.tsx:151:1)

at renderWithHooks (react-dom.development.js:16175:1)

at mountIndeterminateComponent (react-dom.development.js:20913:1)

at beginWork (react-dom.development.js:22416:1)

at HTMLUnknownElement.callCallback (react-dom.development.js:4161:1)

at Object.invokeGuardedCallbackDev (react-dom.development.js:4210:1)

at invokeGuardedCallback (react-dom.development.js:4274:1)

at beginWork$1 (react-dom.development.js:27405:1)

at performUnitOfWork (react-dom.development.js:26513:1)

The above error occurred in the component:

at BrowserRouter (http://localhost:3001/static/js/bundle.js:45400:5)

Consider adding an error boundary to your tree to customize error handling behavior. Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries. logCapturedError @ react-dom.development.js:18572

4 errors with invalid hooks, 3 errors with Uncaught TypeError: Cannot read properties of null (reading 'useRef') and The above error occurred in the <BrowserRouter> component appear in the console once

Here is my code:

src/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { BrowserRouter } from "react-router-dom";

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
  <BrowserRouter>
    <App />
  </BrowserRouter>
  </React.StrictMode>
);

src./App.js

import React from "react";
import ReactDOM from "react-dom";
import {Routes,Route, Link } from "react-router-dom";

function App() {
  return (
    <div className="App">
      <h1>Welcome to React Router!</h1>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="about" element={<About />} />
      </Routes>
    </div>
  );
}

function Home() {
  return (
    <>
      <main>
        <h2>Welcome to the homepage!</h2>
        <p>You can do this, I believe in you.</p>
      </main>
      <nav>
        <Link to="/about">About</Link>
      </nav>
    </>
  );
}

function About() {
  return (
    <>
      <main>
        <h2>Who are we?</h2>
        <p>
          That feels like an existential question, don't you
          think?
        </p>
      </main>
      <nav>
        <Link to="/">Home</Link>
      </nav>
    </>
  );
}
export default App;

and package.json

{
  "name": "ao-app",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^13.2.0",
    "@testing-library/user-event": "^13.5.0",
    "react": "^18.1.0",
    "react-dom": "^18.1.0",
    "react-scripts": "5.0.1",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test", 
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}


I did everything as it is written in the documentation (https://reactrouter.com/docs/en/v6/getting-started/installation)



Solution 1:[1]

I was facing the same issue. Just uninstall the version 6 of the react-router-dom and install it like

npm i react-router-dom

This worked for me!

Solution 2:[2]

I wanted to see if I could make @riccardo-bucco's answer any faster (I could not) but I will show you an alternative that is basically the same speed that I thought might be faster.

To be clear, I feel the top answer is from @riccardo_bucco as it is easier to follow and is just as fast. Use it.

I was hoping that not having to scan the counter twice would more than make up for resetting the largest_with_ties list, but it did not.

def jonsg(data_in):
    largest_with_ties = [(None, 0)]
    for item in collections.Counter(data_in).items():
        diff = item[1] - largest_with_ties[0][1]
        if diff < 0:
            continue
        if diff > 0:
            largest_with_ties.clear()
        largest_with_ties.append(item)
    return sorted(largest_with_ties)

Testing the timings I will use the words from "The Complete Works of William Shakespeare" from Project Guttenberg. You can get that here (5.5m): https://www.gutenberg.org/files/100/100-0.txt

Note, I have slightly altered Riccardo Bucco's answer to return a tuple not that it made a performance difference.

import timeit

setup = """
import collections

#data_in = ['b', 'b', 'a', 'a', 'c']
with open("shakespeare.txt", "r", encoding="utf-8") as file_in:
    data_in = [word.strip().lower() for line in file_in for word in line.split()]

def riccardo_bucco(data_in):
    counts = collections.Counter(data_in) # O(n)
    largest = max(counts.values()) # O(n)
    largest_with_ties = [item for item in counts.items() if item[1] == largest] # O(n)
    return sorted(largest_with_ties)

def jonsg(data_in):
    largest_with_ties = [(None, 0)]
    for item in collections.Counter(data_in).items():
        diff = item[1] - largest_with_ties[0][1]
        if diff < 0:
            continue
        if diff > 0:
            largest_with_ties.clear()
        largest_with_ties.append(item)
    return sorted(largest_with_ties)
"""

Now we can run:

print(f"riccardo_bucco: {timeit.timeit('riccardo_bucco(data_in)', setup=setup, number=100)}")
print(f"jonsg         : {timeit.timeit('jonsg(data_in)', setup=setup, number=100)}")

giving results like:

riccardo_bucco: 10.59
jonsg         : 10.55

Suggesting to me that they perform equally well (or poorly). Feel free to extend this with other attempts.

FYI: The actual most common is: ('the', 30087).

If one wants to test with the individual characters then data_in can be set via:

data_in = [char.lower() for char in file_in.read() if char.strip()]

In that case the most common is [('e', 482212)]

But doing so does not fundamentally alter the relative performance of these solutions.

Solution 3:[3]

Using your code and Counter we get the following:

from collections import Counter

def most_frequent(List):
    occurence_count = Counter(List)
    return occurence_count.most_common()

l = ['b', 'b', 'b', 'a', 'a', 'c']


print(sorted(most_frequent(l)))

We get the output:

[('a', 2), ('b', 3), ('c', 1)]

With sorted we sort the items automatically by alphabet.

You can double check that its sorting alphabetically with the following code:

tuplesInList = (most_frequent(l))
#to sort tuples within lists we use an anonymous function(lambda)
def sort_tuple_vals(my_tup):
    my_tup.sort(key=lambda x:x[0])
    return my_tup

This sorts the tuples by the first element in the tuple

print(sort_tuple_vals(tuplesInList))

gets the output

[('a', 2), ('b', 3), ('c', 1)]

If you want to sort by occurrence as opposed to alphabetically, then sort by alphabetically in case of a tie, the following code should work. We first sort the tuples by the number of occurrences with lambda x: x[1]

tuplesInList = (most_frequent(l))
#to sort tuples within lists we use an anonymous function(lambda)
def sortTupsbyOccurance(my_tup):
    my_tup.sort(key=lambda x:x[1])
    print(my_tup)
    return my_tup

tuple=(sortTupsbyOccurance(tuplesInList))
print(tuple)

from an initial list l = ['b', 'b', 'b', 'a', 'a', 'a', 'c'] we get the output:

[('c', 1), ('b', 3), ('a', 3)]

using this I believe we solve the sorting by alphabet issue. if tuple at position n's second value is equal to the second value of tuple at positon n+1 we note the equality and go to our next if statement with those values. Because we start at position 0 we are sure to not skip any potential matches.

#set the n value for  range 0, n to the number of tuple entries in the list.
for n in range(0,2):
        if tuple[n][1]==tuple[n+1][1]:
           print("there is an equality")
           var1=str(tuple[n][0])
           var2= str(tuple[n+1][0])

           if var1 > var2:
               print(var1, var2)
               print("this is true")
               # if tuple at position n's 1st value (alphabeticaly) is greater than tuple n+1's first value then we switch them.
              
               tuple[n], tuple[n+1] = tuple[n+1], tuple[n]
               print(tuple)

from initial list l with 3 "a"s and 3 "b"s we get the output:

[('c', 1), ('a', 3), ('b', 3)]

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ayush Kumar Bhadani
Solution 2
Solution 3