I am making a react music player (ok, spotify clone). I don't know about redux and any global states So Iam learning context to change states from another components.
Edit: I am using a codesandbox example = https://codesandbox.io/s/react-context-forked-6t8g7l?file=/src/LanguageSwitcher.js
As usual, I am getting error
This is my App.js =>
import React, { useState, useEffect } from 'react';
import { BrowserRouter as Router,
Switch,
Route
} from "react-router-dom";
import IsPlayingContext from './context/IsPlayingContext';
import styles from './style/App.module.css';
function App() {
const [isPlaying,setIsplaying]=useState(false)
const value = { isPlaying,setIsplaying };
return (
<Router >
<div className={styles.layout}>
<IsPlayingContext.Provider value={value} >
{size.width > CONST.MOBILE_SIZE
? <Sidebar />
: <MobileNavigation />
}
<Switch >
<Route exact path="/">
<Home />
</Route>
<Route path="/search">
<Search />
</Route>
<Route path="/library">
<Library />
</Route>
<Route exact path="/playlist/:path">
<PlaylistPage />
</Route>
</Switch>
<Footer />
</IsPlayingContext.Provider>
</div>
</Router>
);
}
export default App;
Footer.js
import React, { useRef, useEffect, useState } from 'react';
import { useContext } from 'react';
import IsPlayingContext from '../../context/IsPlayingContext';
function Footer(props){
const {isPlaying,setIsPlaying} = useContext(IsPlayingContext)
useEffect(() => {
setIsPlaying(true)
// That's the line
}, [])
return (
// Here my usual code
);
}
export default Footer
The error i am getting is =>
Uncaught TypeError: setIsPlaying is not a function
at footer.js:49:1
Please help me I will be very grateful to you
There's a typo mistake, you declared setIsplaying using a small p i in App.js
const [isPlaying,setIsplaying]=useState(false)
const value = { isPlaying,setIsplaying };
and you are accessing it as setIsPlaying where P is a capital letter in the Footer component
const {isPlaying,setIsPlaying} = useContext(IsPlayingContext)
So change it too,
const {isPlaying,setIsplaying} = useContext(IsPlayingContext)
Related
I am learning basic crud operations in React, and ran into this problem. In the components, I am primarily expecting to see one word in each page. But when I am starting the react app, pages appear to be blank. I guess I missed something about react-router or react-router-dom. Codes are given here.
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
reportWebVitals();
App.js
import React from "react";
import ReactDOM from "react-dom/client";
import {
BrowserRouter,
Routes,
Route
} from "react-router-dom";
import books from "./components/books.jsx";
import add from "./components/add.jsx";
import update from "./components/update.jsx";
function App() {
return (
<div className="App">
<BrowserRouter>
<Routes>
<Route path="/" element= {<books />} />
<Route path="/add" element= {<add />} />
<Route path="/update" element= {<update />} />
</Routes>
</BrowserRouter>
</div>
);
}
export default App;
books.jsx
import React from "react";
const books = () => {
return (
<div>books</div>
)
}
export default books;
add.jsx
import React from "react";
const add = () => {
return (
<div>add</div>
)
}
export default add;
update.jsx
import React from "react";
const update = () => {
return (
<div>Update</div>
)
}
export default update;
Sub-directories and files in client directory
enter image description here
Codes may seem incomplete as I have encountered this problem at the halfway. I tried some fixes from youtube and google, but could not right it.
React components are Capitalized. From JSX in Depth:
User-Defined Components Must Be Capitalized
When an element type starts with a lowercase letter, it refers to a
built-in component like <div> or <span> and results in a string
'div' or 'span' passed to React.createElement. Types that start
with a capital letter like <Foo /> compile to
React.createElement(Foo) and correspond to a component defined or
imported in your JavaScript file.
By using <book /> React assumes this is an HTML element and doesn't create a React element from your component code.
import React from "react";
const Books = () => {
return (
<div>books</div>
)
}
export default Books;
import Books from "./components/books.jsx";
import Add from "./components/add.jsx";
import Update from "./components/update.jsx";
function App() {
return (
<div className="App">
<BrowserRouter>
<Routes>
<Route path="/" element={<Books />} />
<Route path="/add" element={<Add />} />
<Route path="/update" element={<Update />} />
</Routes>
</BrowserRouter>
</div>
);
}
I am doing a personal React.js project. I am trying to use react-router-dom, but I haven't been able to make it work. I did the BrowserRouter in the App.js. Till there the app works fine, but I cannot make the routing redirect dynamically to a map item. I tried to follow the documentation and some tutorials unsuccesfully. The data comes from the Star Wars API This is the code:
App.js:
import './App.css';
import { Route, BrowserRouter as Router, Routes } from "react-router-dom";
import Home from './components/Home';
import MovieDetail from './components/MovieDetail'
import Navbar from './components/Navbar';
function App() {
return (
<Router>
<>
<Navbar />
<Routes>
<Route exact path='/' element={<Home />} />
</Routes>
<Routes>
<Route exact path to='/:movieId' element={<MovieDetail />} />
</Routes>
</>
</Router>
);
}
export default App;
ItemDetail:
import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
const MovieDetail = () => {
const { movieId } = useParams();
const [result, setResult] = useState([]);
const fetchData = async () => {
const res = await fetch("https://www.swapi.tech/api/films/");
const json = await res.json();
setResult(json.result);
}
useEffect(() => {
fetchData();
}, []);
let movieMatch = (result.find(value) => value.properties.title == movieId)
return (
<div>
<h2>
{result
.find((value) => {value.properties.title == movieId})}
</h2>
</div>
);
}
export default MovieDetail;
UPDATE
This is a link to the whole code in codesand with updated App.js
From your code I'm assuming you're using React Router v6 in your project. Try the below code:
import './App.css';
import { BrowserRouter, Routes, Route } from "react-router-dom";
import Home from './components/Home';
import MovieDetail from './components/MovieDetail'
import Navbar from './components/Navbar';
function App() {
return (
<BrowserRouter>
<Routes>
<Navbar />
<Route path='/' element={<Home />} />
<Route path=':movieId' element={<MovieDetail />} />
</Routes>
</BrowserRouter>
);
}
export default App;
Checkout React Router's Documentation for more detail.
if you are using index.js as a wrapper for app.js <BrowserRouter /> or <Router /> in your case is not used in app.js it's used in index.js otherwise it will not work
index.js should look like this : -
import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom";
function App() {
return <h1>Hello React Router</h1>;
}
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById("root")
);
**For example just Let's say you are having "/movies" route and you want when ever your app (route = "/") starts / loads up to be redirected to "/movies" **
then wrap the routing logic with *<Switch />* ,make use of Redirect property of router dom to redirect from "/" to "/movies" and use component instead of element to render the corresponding component plus dont wrap with <Routes> </Routes> every time you are doing the route as we used it in index.js
then app.js will be : -
import './App.css';
import { Route, BrowserRouter as Router, Routes } from "react-router-dom";
import Home from './components/Home';
import MovieDetail from './components/MovieDetail'
import Navbar from './components/Navbar';
function App() {
return (
<>
<Navbar />
<Switch>
<Route exact path='/movies' component={<Home />} />
<Route exact path to='movies/:movieId' component={<MovieDetail />}
// to redirect from "/" to "/movies"
<Redirect from="/" to="/students"></Redirect>
);
}
Please help me
When the Route is not inside <Routes> it gives an error:
Error: A is only ever to be used as the child of element, never rendered directly. Please wrap your in a
When it is inside <Routes> it give an error as:
Error: [Abc] is not a <Route> component. All component children of must be a <Route> or <React.Fragment>
Pls help me to resolve this situation? Or any suggestion.
Tried this but one of the above error in both cases.
As this does not generate an error, however my child component of the private route does not render.
import React from 'react'
import './App.css'
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import Header from './components/Header'
import Home from './components/Home'
import Login from './components/Login'
import ProtectedRoute from './components/Helper/ProtectedRoute';
import { UserStorage } from './UserContext';
import User from './components/User';
const App = () => {
return (
<div>
<BrowserRouter>
<UserStorage>
<>
<Header />
<Routes>
<Route path="/" element={<Home />} />
<Route path="login/*" element={<Login />} />
<Route path='/conta' element={<ProtectedRoute/>}>
<Route path='/conta' element={<User/>}/>
</Route>
</Routes>
</>
</UserStorage>
</BrowserRouter>
</div>
)
}
export default App;
ProtectedRoute
import React from 'react';
import { UserContext } from '../../UserContext';
import {Routes, Route, Navigate } from 'react-router-dom';
const ProtectedRoute = (props) => {
const { login } = React.useContext(UserContext);
if (login === true) return (
<Routes>
<Route {...props} />
</Routes>
);
else if (login === false) return <Navigate to="/login" />;
else return null;
};
export default ProtectedRoute;
With layout wrapper components like ProtectedRoute that renders nested Route components then you need to ensure it is rendering an Outlet for them to be rendered into.
Outlet
import React from 'react';
import { UserContext } from '../../UserContext';
import {Routes, Route, Navigate } from 'react-router-dom';
const ProtectedRoute = () => {
const { login } = React.useContext(UserContext);
if (login === undefined) return null;
return login
? <Outlet /> // <-- nested Route components rendered here
: <Navigate to="/login" replace />;
};
...
<Route path='/conta' element={<ProtectedRoute/>}>
<Route path='/conta' element={<User/>}/> // <-- rendered into outlet
</Route>
I'm trying to develop a slide-out menu with routing function for React. for some reason state = {} isn't setting defining sideDrawOpen what could the reasons for this be thanks for your help. the error I get running yarn start is
"Failed to compile.
./src/App.js
Line 21:45: 'sideDrawerOpen' is not defined no-undef
Search for the keywords to learn more about each error."
import React, { Component } from 'react';
import {BrowserRouter as Router, Switch, Route} from 'react-router-dom';
import main_page from './components/main_page';
import setup_page from './components/setup_page';
import settings_page from './components/settings_page';
import Error from './components/Error';
import Nav from './components/Navigation/Nav';
import SideDrawer from './components/Navigation/SideDrawer';
import Backdrop from './components/Navigation/Backdrop';
export class App extends Component {
state = {
sideDrawerOpen: false
}
drawerToggleClickHandler = () => {
this.setState((prevState) =>{
return {sideDrawerOpen: !prevState,sideDrawerOpen};
});
};
render() {
let sideDrawer;
let backdrop;
if (this.state.sideDrawerOpen) {
sideDrawer = <SideDrawer />
backdrop = <Backdrop />
}
return (
<div className="App_margin">
<Router>
<div className='App'>
{sideDrawer}
{backdrop}
<Nav />
<Switch>
<Route path='/' component={setup_page} exact/>
<Route path='/main_page' component={main_page} />
<Route path='/settings_page' component={settings_page} />
<Route component={Error} />
</Switch>
</div>
</Router>
</div>
);
}
}
!prevState,sideDrawerOpen has a comma, not a .
I'm just doing some basic routing in my react app and I've done it this way before so I'm pretty confused to as why it isn't working now.
The error I am getting says: You should not use <Route> or withRouter() outside a <Router>
I'm sure this is super basic so thanks for baring with me!
import React from 'react'
import { Route } from 'react-router-dom'
import { Link } from 'react-router-dom'
import * as BooksAPI from './BooksAPI'
import BookList from './BookList'
import './App.css'
class BooksApp extends React.Component {
state = {
books: []
}
componentDidMount() {
this.getBooks()
}
getBooks = () => {
BooksAPI.getAll().then(data => {
this.setState({
books: data
})
})
}
render() {
return (
<div className="App">
<Route exact path="/" render={() => (
<BookList
books={this.state.books}
/>
)}/>
</div>
)
}
}
export default BooksApp
You need to setup context provider for react-router
import { BrowserRouter, Route, Link } from 'react-router-dom';
// ....
render() {
return (
<BrowserRouter>
<div className="App">
<Route exact path="/" render={() => (
<BookList
books={this.state.books}
/>
)}/>
</div>
</BrowserRouter>
)
}
Side note - BrowserRouter should be placed at the top level of your application and have only a single child.
I was facing the exact same issue. Turns out that i didn't wrap the App inside BrowserRouter before using the Route in App.js.
Here is how i fixed in index.js.
import {BrowserRouter} from 'react-router-dom';
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>
document.getElementById('root')
);