import { useEffect, useState } from "react";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Detail from "../components/Detail";
import Popular from "../components/Popular";
import Home from "../components/Home ";
import Trending from "../components/Trending";
import Upcoming from "../components/Upcoming";
import TopRated from "../components/TopRated";
import NowPlaying from "../components/NowPlaying";
function App() {
return (
<Router>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/popular-mv" element={<Popular type="movie" />} />
<Route path="/trending-mv" element={<Trending type="movie" />} />
<Route path="/topRated-mv" element={<TopRated type="movie" />} />
<Route path="/upcoming-mv" element={<Upcoming type="movie" />} />
<Route path="/nowPlaying-mv" element={<NowPlaying type="movie" />} />
<Route path="/popular-tv" element={<Popular type="tv" />} />
<Route path="/trending-tv" element={<Trending type="tv" />} />
<Route path="/topRated-tv" element={<TopRated type="tv" />} />
<Route path="/nowPlaying-tv" element={<NowPlaying type="tv" />} />
<Route path="/detail/:id/:type" element={<Detail />} />
</Routes>
</Router>
);
}
export default App;
import { useState, useEffect } from "react";
import { useParams, Link, useLocation } from "react-router-dom";
function Detail() {
const type =
useLocation().pathname.split("/")[
useLocation().pathname.split("/").length - 1
];
const URL = `https://api.themoviedb.org/3/${type}/`;
const { id } = useParams();
const [details, setDetails] = useState([]);
const [similars, setSimilars] = useState([]);
const [genres, setGenres] = useState([]);
function detailFetch() {
fetch(`${URL}${id}?api_key=${API_KEY}`)
.then((result) => result.json())
.then((json) => {
setDetails(json);
setGenres(json.genres);
});
}
function similarFetch() {
fetch(`${URL}${id}/similar?api_key=${API_KEY}`)
.then((result) => result.json())
.then((json) => {
setSimilars(json.results);
});
}
useEffect(() => {
detailFetch();
similarFetch();
}, []);
return (
<div>
<img src={`https://image.tmdb.org/t/p/w500/${details.poster_path}`} />
<div>{details.title}</div>
<div>{details.vote_average}</div>
<div>{details.release_date}</div>
<div>{details.runtime}</div>
<div>
{genres.map((g) => (
<li key={g.id}>{g.name}</li>
))}
</div>
<p>{details.overview}</p>
<div>
{similars.map((s) => (
<a href={`/detail/${s.id}/${type}`} key={s.id}>
<img src={`https://image.tmdb.org/t/p/w500/${s.poster_path}`} />
</a>
))}
</div>
</div>
);
}
export default Detail;
I'm making movieApp using react.
but i have some problems about routing.
As i said at title, in movie information(detail) page, i made this page load when clicking movie poster and its similar movies. and then i cliked similar movie poster, i expected to reload the page.
Actially i solve this problem using not using .
But i have question why this is not working when i using
(i have other pages like tv list,movie list. but it only occurs in detail page.)
Thank You!
Related
The problem is really simple. I fetched the data and stored it in state. When passing to other components it logs okay, on a second render I get what I want(array of objects). But when I pass the same array to Fahrzeugdaten component, I get undefined on a second render.
PS. No need to write about different ways of state management, I need a simple answer.
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import {
Datenschutz,
Fahrzeugangebote,
Fahrzeugankauf,
Finanzierung,
Galerie,
Home,
Impressum,
Kontakt,
Fehler404,
Fahrzeugdaten,
} from './pages';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import './App.css';
const App = () => {
const [carsList, setCarsList] = useState();
useEffect(() => {
fetchCars();
}, []);
const fetchCars = async () => {
try {
const res = await axios.get(url);
const data = res.data;
setCarsList(data);
} catch (error) {
console.log(error.response.data.error);
}
};
return (
<Router>
<Routes>
<Route path='/' element={<Home />} />
<Route path='/datenschutz' element={<Datenschutz />} />
<Route
path='/fahrzeugangebote'
element={<Fahrzeugangebote />}
/>
<Route path='/fahrzeugankauf' element={<Fahrzeugankauf />} />
<Route path='/finanzierung' element={<Finanzierung />} />
<Route path='/galerie' element={<Galerie />} />
<Route path='/impressum' element={<Impressum />} />
<Route path='/kontakt' element={<Kontakt />} />
<Route path='*' element={<Fehler404 />} />
<Route path='/fahrzeugdaten/:id'
element={<Fahrzeugdaten carsList={carsList} />}/>
</Routes>
</Router>
);
};
export default App;
Fahrzeugdaten component:
import React from 'react';
import { Header, Navbar, Jumbotrone, Logo, CarPage } from '../components';
const Fahrzeugdaten = ({ carsList }) => {
return (
<>
<div id='header-img-id' className='header-img-div'>
<Header />
<Navbar />
<div className='mka__logo-img'>
<div className='mka__logo-size'>
<Logo />
</div>
</div>
<div className='mka__title-wrapper'>
<div className='mka__container'>
<h1 className='mka__title'>FAHRZEUGDATEN</h1>
</div>
</div>
</div>
<div>
<CarPage />
</div>
<Jumbotrone />
</>
);
};
export default Fahrzeugdaten;
I have a react component index.js that fetches the user information from a Laravel server through a fetch call. The information is provided to the context UserContext, which is declared in a separate file and imported, near the top-level of the app as follows.
UserContext.jsx
import { createContext } from "react";
const UserContext = createContext(null);
export default UserContext;
const [user, setUser] = useState(null);
useEffect(() => {
// Get logged in user
fetch('/user', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
},
credentials: 'include'
}).then(res => res.json()).then(data => {
setUser(data);
}).catch(err => {
setUser(null)
});
}
return (
<UserContext.Provider value={user}>
<Header/>
<main>
<BrowserRouter>
<Routes>
<Route path="/" element={<Home categories={categories} />} />
<Route path="/login" element={<Login />} />
<Route path="/register" element={<Register />} />
<Route path="/profile/:id" element={<Profile />} />
<Route path="/profile/:id/edit" element={<EditProfile />} />
<Route path="/profile/:id/registrations" element={<MyRegistrations />} />
<Route path="/posts" element={<Posts />}></Route>
<Route path="/posts/:id" element={<Post categories={categories} />}></Route>
<Route path="/category/:id" element={<Posts />} />
<Route path="/403" element={<Error error={403} />} />
<Route path="/404" element={<Error error={404} />} />
<Route path="/500" element={<Error error={500} />} />
<Route path="*" element={<Error error={404} />} />
</Routes>
</BrowserRouter>
</main>
<Footer/>
</UserContext.Provider>
);
When I try to access user in <Header>, it works as expected. However, in the routes nested in the react-router-dom <Routes>, it returns null.
Header.jsx, Post.jsx declaration to access user
const user = useContext(UserContext);
I suspected that this could be caused because of the context provided by react-router-dom or the nesting, so I tried to pull <Post/> to the top level and disable react-router-dom but it seems to be the same issue.
Post.jsx
import { useState, useEffect, useContext } from 'react';
import React from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import * as DOMPurify from 'dompurify';
import { Container } from 'react-bootstrap';
import UserContext from '../context/userContext';
export default function Post({ categories }) {
const user = React.useContext(UserContext);
let navigate = useNavigate();
let params = useParams();
const [id, setId] = useState(params.id);
const [post, setPost] = useState(null);
const [registered, setRegistered] = useState(false);
const inCourse = (id, courses) => {
console.log(id, courses);
return courses.filter(course => course.id == id).length > 0;
}
const inEvent = (id, events) => {
return events.filter(event => event.id == id).length > 0;
}
useEffect(() => {
{/* fetch post from api, works correctly */}
}, [id]);
useEffect(() => {
}, [user, id]);
return (
{/* unnecessary jsx */}
);
}
The problem is that when I start using React.lazy, input styles are not rendering correctly. With lazy I get default Antd input styles, not mine. What's the problem and how I can fix it? You can see my code and its results in the pictures below. Thanks!
This picture shows styles that this component should render
This picture shows what styles are applied when using lazy
Code with lazy
import { lazy, Suspense } from 'react';
import { Routes, Route, Navigate } from 'react-router-dom';
import { useAppSelector } from '../../../hooks/redux-hooks';
import { selectCurrentUser } from '../../../store/slices/user/userSelectors';
import { Spinner } from '../../common/Spinner/Spinner';
const HomePage = lazy(() => import('../../../pages/HomePage'));
const ShopPage = lazy(() => import('../../../pages/ShopPage'));
const CheckoutPage = lazy(() => import('../../../pages/CheckoutPage'));
const AuthPage = lazy(() => import('../../../pages/AuthPage'));
export const AppRoutes = () => {
const currentUser = useAppSelector(selectCurrentUser);
return (
<Suspense fallback={<Spinner />}>
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="shop/*" element={<ShopPage />} />
<Route path="checkout" element={<CheckoutPage />} />
<Route
path="auth"
element={currentUser ? <Navigate to="/" /> : <AuthPage />}
/>
</Routes>
</Suspense>
);
};
Code without lazy
import { Routes, Route, Navigate } from 'react-router-dom';
import { useAppSelector } from '../../../hooks/redux-hooks';
import { selectCurrentUser } from '../../../store/slices/user/userSelectors';
import HomePage from '../../../pages/HomePage';
import ShopPage from '../../../pages/ShopPage';
import AuthPage from '../../../pages/AuthPage';
import CheckoutPage from '../../../pages/CheckoutPage';
export const AppRoutes = () => {
const currentUser = useAppSelector(selectCurrentUser);
return (
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="shop/*" element={<ShopPage />} />
<Route path="checkout" element={<CheckoutPage />} />
<Route
path="auth"
element={currentUser ? <Navigate to="/" /> : <AuthPage />}
/>
</Routes>
);
};
So I'm trying to redirect the Add to Cart button to Cart screen but it isn't working
ProductScreen.js
useNavigate() redirects to the link but doesn't display anything
import React, { useState, useEffect } from 'react'
import { Link, useParams, useNavigate } from 'react-router-dom'
import { useDispatch, useSelector } from 'react-redux'
const ProductScreen = () => {
const { id } = useParams()
const navigate = useNavigate()
const [ qty, setQty ] = useState(0)
const dispatch = useDispatch()
const productDetails = useSelector(state => state.productDetails)
const { loading, error, product } = productDetails
useEffect(() => {
dispatch(listProductDetails(id))
}, [dispatch])
return (
<>
<ListGroup.Item className='d-grid gap-2'>
<Button
onClick={() => navigate(`/cart/${id}?qty=${qty}`)}
className='btn-block'
type='button'
size='lg'
disabled={product.countInStock === 0}
> Add to Cart </Button>
</ListGroup.Item>
</>
)
}
CartScreen.js
const CartScreen = () => {
return (
<h1>Cart</h1>
)
}
export default CartScreen
App.js
import React from 'react'
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom'
import { Container } from 'react-bootstrap'
import Footer from './components/Footer'
import Header from './components/Header'
import HomeScreen from './screens/HomeScreen'
import ProductScreen from './screens/ProductScreen'
import CartScreen from './screens/CartScreen'
const App = () => {
return (
<Router>
<Header />
<main className='py-3'>
<Container>
<Routes>
<Route path='/' element={<HomeScreen />} exact />
<Route path='/product/:id' element={<ProductScreen />} />
<Route path='/cart' element={<CartScreen />}>
<Route path='/cart/:id?' element={<CartScreen />} />
</Route>
</Routes>
</Container>
</main>
<Footer />
</Router>
)
}
export default App
Now, this is where the problem lies. As far as I know, the cart screen should be displayed but all I get is a blank screen.
I get this one issue on console screen that I can't put my finger on
No routes matched location "/cart/6239f6707dfb138e900d42d7?qty=2"
I am very new to this coz everything has changed from the last version. I know this is very simple but I'm stuck here and can't go any further... Thanks for your help in advance
It seems like you maybe be using nested routes incorrectly in order to achieve what you are supposed to:
With this nesting:
<Route path='/cart' element={<CartScreen />}>
<Route path='/cart/:id?' element={<CartScreen />} />
</Route>
The above will match:
/cart/cart/6239f6707dfb138e900d42d7?qty=2
Shouldn't the nesting be?:
<Route path='/cart' element={<CartScreen />}>
<Route path='/:id?' element={<CartScreen />} />
</Route>
in order to to match:
/cart/6239f6707dfb138e900d42d7?qty=2
Perhaps you may have forgotten to use <Outlet /> to render content in <CartScreen />?
I'm trying to get an id from the useParams, but getting Property employeeId does not exist on type error and I don't understand why.
Here is the routes.tsx
//I omitted all the imports here
import React from 'react';
import { BrowserRouter as Router, Routes, Route, Outlet } from 'react-router-dom';
const DefaultContainer = (): JSX.Element => (
<div>
<div id="header">
<Header />
</div>
<div>
<div id="main-container">
<Outlet />
</div>
</div>
</div>
);
const AllRoutes = () => (
<Router>
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/" element={<DefaultContainer />}>
<PrivateRoute path="/" element={<Home />} />
<PrivateRoute path="/e/employees" element={<EmployeeList />} />
<PrivateRoute path="/e/add" element={<AddEmployee />} />
<PrivateRoute path="/e/:employeeId" element={<Employee />} />
<PrivateRoute path="/e/update/:employeeId" element={<UpdateEmployee />} />
</Route>
</Routes>
</Router>
);
export default AllRoutes;
Here is my UpdateEmployee.component.tsx
import React from 'react';
import { useParams } from 'react-router';
const UpdateEmployee = () => {
const { employeeId } = useParams();
console.log(employeeId);
return <h1>hello world</h1>
}
In the routes.tsx there is /e/:employeeId it is working fine.
I also tried adding type for employeeId as string, but still no luck.
Really appreciate your help.
PrivateRoutes.component.tsx
import React from 'react';
import { Navigate, Route } from 'react-router-dom';
import { useAppDispatch, useAppSelector } from '../../hooks/reduxHooks';
import { setUser } from '../../services/reducers/Auth.reducer';
const PrivateRoute = ({ element, ...rest }) => {
const dispatch = useAppDispatch();
const localStorageData = localStorage.getItem('user');
const user = localStorageData ? JSON.parse(localStorageData) : null;
if (!user) {
return <Navigate to="/login" />;
}
// This will reload the user from localstorage in redux state.
const stateUser = useAppSelector((state) => state.auth.user);
if (!stateUser) {
dispatch(setUser(user));
}
return <Route element={element} {...rest} />;
};
export default PrivateRoute;
Try with setting to any type, this worked for me.
const { employeeId } : any = useParams();