I'm trying to build my homepage but I'm getting the below errors in my terminal and my react page is blank. Any suggestions on what I change to fix these errors? Thanks in advance
Line 4:8: 'Cart' is defined but never used
Line 7:27: 'Router' is defined but never used
Line 7:50: 'Link' is defined but never used
Line 17:8: 'page' is assigned a value but never used
Line 28:9: 'addToCart' is assigned a value but never used
import React, { useState } from "react";
import "./Homepage.css";
import Shop from "./Shop";
import Cart from "./Cart";
import About from "./About";
import ContactUs from "./ContactUs";
import { BrowserRouter as Router, Routes, Route, Link } from "react-router-dom";
const PAGE_SHOP = "shop";
const PAGE_CART = "cart";
const PAGE_HOMEPAGE = "home";
export default function Homepage() {
const [cart, setCart] = useState([]);
const [page, setPage] = useState(PAGE_SHOP);
const navigateTo = (nextPage) => {
setPage(nextPage);
};
const getCartTotal = () => {
return cart.reduce((sum, { quantity }) => sum + quantity, 0);
};
const addToCart = (product) => {
let newCart = [...cart];
let itemInCart = newCart.find((item) => product.name === item.name);
if (itemInCart) {
itemInCart.quantity++;
} else {
itemInCart = {
...product,
quantity: 1,
};
newCart.push(itemInCart);
}
setCart(newCart);
};
return (
<div className="Header">
<header>
<button onClick={() => navigateTo(PAGE_CART)}>
Go to Cart ({getCartTotal()})
</button>
<button onClick={() => navigateTo(PAGE_SHOP)}>Shop</button>
</header>
<router>
<Routes>
<Route path="/" element={<PAGE_HOMEPAGE />} />
<Route path="/About" element={<About />} />
<Route path="/Shop" element={<Shop />} />
<Route path="/ContactUs" element={<ContactUs />} />
</Routes>
</router>
</div>
);
}
You have set const PAGE_HOMEPAGE = 'home';
If you look at the following line
<Route path="/" element={<PAGE_HOMEPAGE />} />
You are passing a string instead of an element.
Replace PAGE_HOMEPAGE with a react component that you would like to render on path '/'
To remove the warnings, just remove the code mentioned in those warnings, if you don't intend on using it.
If you do plan on using it, ignore the warnings for now and they will go away once the code is used.
Related
I am trying to use the react context api. I am experiencing an issue though where the context/state value is not updating. I have no idea why this is happening and have looked at numerous threads but have found that nothing works for me.
Here is the code:
curtain-context.js
For creating the contexts and exporting them:
const CurtainContext = createContext({
curtainVisible: false,
setCurtainVisible: (value) => {}
});
export function CurtainContextProvider(props) {
const [curtainVisible, setCurtainVisible] = useState();
function setCurtainVisibleHandler(value) {
setCurtainVisible(value);
console.log(value);
}
const context = {
curtainVisible: curtainVisible,
setCurtainVisible: setCurtainVisibleHandler
};
return (
<CurtainContext.Provider value={context}>
{props.children}
</CurtainContext.Provider>
);
}
export default CurtainContext;
App.js
The main application code which is surrounded by the context provider:
<Layout>
<CurtainContextProvider>
<Routes>
<Route element={<HomePage/>} path='/' exact/>
<Route element={<HomePage/>} path='/home' exact/>
<Route element={<ServicesPage/>} path='/services' exact/>
<Route element={<ProductsPage/>} path='/products' exact/>
<Route element={<ContactPage/>} path='/contact' exact/>
<Route element={<LoginPage/>} path='/login' exact/>
</Routes>
</CurtainContextProvider>
</Layout>
MainNavigation.js
The place where I want to use the context value to render something if curtainVisible is true:
import { NavLink } from 'react-router-dom';
import classes from './MainNavigation.module.css';
import React, {useContext, useState} from "react";
import { useLocation } from "react-router";
import MobileCurtain from "../ui/MobileCurtain";
import CurtainContext from "../../store/curtain-context";
function MainNavigation() {
var curtainContext = useContext(CurtainContext);
const { pathname } = useLocation();
const activeClass = ({isActive}) => (isActive ? classes.active : classes.inactive);
const activeUserClass = ({paths = ['/login', '/settings']}) => (paths.includes(pathname) ? classes.active : classes.inactive);
function handleBarsClicked() {
curtainContext.setCurtainVisible(true);
}
return (
<div className={classes.menu}>
<ul>
<li className={classes.textLinkBars}><button className={classes.iconButton} onClick={handleBarsClicked}><FontAwesomeIcon icon={faBars} className={classes.bars}/></button></li>
{ curtainContext.curtainVisible ? <MobileCurtain/> : null}
<li className={classes.textLink}><NavLink to="/" className={activeClass}>Home</NavLink></li>
<li className={classes.textLink}><NavLink to="/services" className={activeClass}>Services</NavLink></li>
<li className={classes.textLink}><NavLink to="/products" className={activeClass}>Products</NavLink></li>
<li className={classes.textLink}><NavLink to="/contact" className={activeClass}>Contact</NavLink></li>
</div>
</ul>
</div>
);
}
export default MainNavigation;
Only components that are descendants of the Provider can use context value.
In your example, MainNavigation isn't a descendant of CurtainContextProvider hence the issue.
You set your initial value to
{
curtainVisible: false,
setCurtainVisible: (value) => {}
}
which didn't helped, because this (value) => {} was run instead of setCurtainVisibleHandler.
I would suggest using undefined as an initial value of context
Also, hooks like this can help prevent the issue like yours:
const useCurtainContext = () => {
const context = useContext(CurtainContext);
if (!context) {
throw new Error('`useCurtainContext` have to be used inside `CurtainContextProvider`')
}
return context
}
I'm stuck on trying to build a blog, and I have no idea how to fetch specific data from GraphQL API to a dynamic page.
What I try to build:
There's a page called /blog with multiple Card Components. Each card is made of an image, a title and a datePosted. Each of these Cards is a Blog Post. When a user tries to click on a blog post, it clicks on a card and it's being taken to a page like /blog/posts/slug here. So far so good.
The issue:
I have no idea how to make a page dynamic and fetch the specific data from the blog post that has been clicked to a page that can be dynamic. I figure I need to use useParams in React.Js or something like that, but I have no idea how to get the specific post that's been clicked. I can only get all of them.
The code:
1) The /blog page (where I fetch all the posts - this is working properly):
import React from 'react';
import './Blog.styles.scss';
import {GraphQLClient, gql} from 'graphql-request';
import { useState } from 'react';
import { useEffect } from 'react';
import {Link} from 'react-router-dom';
const graphcms = new GraphQLClient('https://api-eu-central-1.hygraph.com/v2/cl66hwcamapj001t76qqlhkl8/master');
const QUERY = gql`
{
posts {
id,
title,
datePublished,
slug,
content{
html
},
coverPhoto{
url
}
}
}
`;
const Blog = () => {
const [posts, setPosts] = useState([]);
useEffect(() => {
const getPosts = async () => {
const {posts} = await graphcms.request(QUERY);
setPosts(posts);
}
getPosts();
}, [])
return (
<div className='blog-container'>
<div className='posts-wrapper'>
{posts && posts.map((post) => (
<div className='blog-card'>
<Link to={'/posts/' + post.slug}>
<div className='blog-card-img-container'>
{post.coverPhoto && <img src={post.coverPhoto.url} alt='blog-card-cover-img'/>}
</div>
<div className='blog-card-title-container'>
<h1 className='blog-card-title'>{post.title}</h1>
</div>
</Link>
</div>
))}
</div>
</div>
)
}
export default Blog
2) The dynamic page that should display ONLY the post that has been previously clicked ->
import React, { useState } from 'react';
import { useEffect } from 'react';
import { useParams } from 'react-router-dom';
import {GraphQLClient, gql} from 'graphql-request';
const graphcms = new GraphQLClient('https://api-eu-central-1.hygraph.com/v2/cl66hwcamapj001t76qqlhkl8/master');
const QUERY = gql`
query Post($slug: String!) {
post(where: {slug: $slug}) {
id,
title,
slug,
datePublished,
content{
html
}
coverPhoto{
url
}
}
}
`;
// const SLUGLIST = gql`
// {
// posts {
// slug
// }
// }
// `;
const BlogPost = () => {
const {slug} = useParams();
const [postData, setPostData] = useState({});
useEffect(() => {
const getPost = async () => {
// const slugs = await graphcms.request(SLUGLIST);
const data = await graphcms.request(QUERY);
setPostData(data);
}
getPost();
}, [slug])
useEffect(() => {
console.log(postData);
}, [postData, slug]);
return (
<div>BlogPost</div>
)
}
export default BlogPost
3) The Routes page:
function App() {
return (
<Routes>
<Route path='/' element={<Navbar />}>
<Route index element={<Homepage />}/>
<Route path='/despre-noi' element={<DespreNoi />} />
<Route path='/galerie' element={<Galerie />}/>
<Route path='/contact' element={<Contact />} />
<Route path='/blog' element={<Blog />} />
<Route path='/animatori' element={<Animatori />} />
<Route path='/ursitoare' element={<Ursitoare />} />
<Route path='/oglinda-magica' element={<OglindaMagica />} />
<Route path='/loc-de-joaca' element={<LocDeJoaca />} />
<Route path='/posts/*' element={<BlogPost />} />
</Route>
</Routes>
)
}
export default App;
NOTE: I know the styles and everything is not refined yet, I'm just trying to get it to work. Any help would be much, much appreciated! Thank you!
Can't actually run your example to see fully what's up but I did notice these 2 things:
1). You want to setup the routes to be based so that you can grab the post id/slug from the url. In react-router this can be done with path=":id" syntax.
<Route path="posts" >
<Route path=":slug" element={<BlogPost />} />
</Route>
https://reactrouter.com/docs/en/v6/components/route
2). Graphql request needs to send the slug along as a variable.
The query Post($slug: String!) expects to be given the slug as a variable.
const variables = {
slug: slug
}
const data = await graphcms.request(QUERY, variables);
Example:
https://github.com/prisma-labs/graphql-request#using-graphql-document-variables
I am trying to load a variable from API, then import it in another file and show/change its value. I'm using Axios for importing jsons. Example code:
main.jsx
//imports of files and libraries
const rootElement = document.getElementById("root");
render(
<BrowserRouter>
<Navbar/>
<Routes>
<Route path="/" element={<App />} />
<Route path="secondarypage" element={<SecondaryPage/>} />
<Route path="firstpage" element={<FirstPage/>} />
<Route path="*" element={<NotFound />}/>
</Routes>
</BrowserRouter>,
rootElement
);
FirstPage.jsx (most of the code is just loading and displaying the JSON data)
The variables are declared here
import { useState, useEffect } from "react";
import Axios from 'axios'
export default function PrimaryFile() {
const [accountsList, setAccountsList] = useState([])
const [AccountName, setAccountName] = useState("")
const [currentUser, setCurrentUser] = useState("Test")
const selectAccount = (e) => {
setCurrentUser(e.target.value)
console.log(currentUser);
}
useEffect(() => {
Axios.get('http://localhost:3030/api/getAccounts').then((response)=> {
setAccountsList(response.data);})
}, [])
const submitAccount = () => {
Axios.post("http://localhost:3030/api/insertAccount", {
OwnerNickname: AccountName,
Token: Tokens
})
setAccountsList([
...accountsList,
{AccountName: AccountName}
])
}
const deleteAccount = (account, tokens) => {
Axios.delete(`http://localhost:3030/api/delete/${account}//${tokens}`)
}
return (
<main>
<h2>Accounts 👥 {currentUser}</h2>
<div>
{accountsList.map((val)=>{
return(
<div>
<div>
<h1>Name: {val.AccountName}</h1>
<h1>Tokens: {val.Tokens}</h1>
</div>
//selecting account here
<div>
<button value={val.AccountName} onClick={selectAccount}> Select 👤</button>
</div>
</div>
)
}) }
</div>
</main>
);
}
SecondaryFile.jsx
Here I want to display and change the value of the variable (for example {CurrentUser} and show it in PrimaryFile.jsx
import { useState, useEffect } from "react";
export default function SecondaryFile() {
const [currentUser, setCurrentUser] = useState("Test")
return(
for example imagine a button that changes the CurrentUser name to blank (or an input)
setCurrentUser()
)
I have a React app which doens't have a route to / setup, so I placed a redirect inside the Switchcomponent, so whenever the user tries to access home they are redirected to the UserHome component.
The Switch set-up is as follows:
const AppRoutes = () => (
<Switch>
<Redirect
exact
from="/"
to={ROUTES.CITIZEN}
/>
<Route
exact
path="/login"
component={Login}
/>
<AuthenticatedRouteRedirect
path={ROUTES.CITIZEN}
component={UserHome}
/>
<AuthenticatedRouteRedirect
path={ROUTES.ADMIN_REPORT_LIST}
component={reportList}
/>
<Route
path="/404"
component={ErrorView}
/>
<Route
component={ErrorView}
/>
</Switch>
And AuthenticatedRouteRedirect as follows:
const AuthenticatedRouteRedirect = ({
component: Component, path = '', exact = false, ...rest
}) => {
const { user } = useAuth();
return (
<Route
path={path}
exact={exact}
render={() => (user
? <Component {...rest} />
: <Redirect to="/login" />)}
/>
);
};
export default AuthenticatedRouteRedirect;
And my UserHome component:
const Dashboard = () => (
<>
<Navbar />
<Container>
<ActionMenu />
</Container>
</>
);
where ActionMenu component uses a custom hook called useReportsLocations, which its implementation is:
import React from 'react';
import { useHistory, useParams } from 'react-router-dom';
import { getMapPolygons, mexicoMap } from 'core/map-locations';
const useReportsLocations = (selectedGroup) => {
const { push } = useHistory();
const { state, municipality } = useParams();
const locationData = React.useMemo(() => {
const currentSelection = {
country: mexicoMap,
state,
municipality,
group: selectedGroup,
};
return getMapPolygons(currentSelection);
}, [municipality, selectedGroup, state]);
React.useEffect(() => {
if (!locationData?.stateData
|| !Object.keys(locationData?.stateData?.municipality
|| {}).includes(municipality)) {
push('/404');
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [municipality]);
return {
locationData,
state,
municipality,
};
};
export default useReportsLocations;
Here's a little demo on CodeSandBox
But when trying to access /, this error message is displayed with the next stacktrace, sorry if it's too large:
What is the cause for this to happen? And how to fix it?
I'm having a bad time trying to figure out whatever the cause is, but simply I can't.
Thank you for your answer and replies.
Pd
I finally figured out what's happening.
After I read the docs, as Redirect leads me to a route where some params are required, but I don't provide any ones to to (as seen in the ROUTES file), it has only the placeholders of {ROUTES.CITIZEN} route, and path-to-regexp#^1.7.0 will complaint that it has been passed nothing and coudn't not resolve to anything.
This behaviour is expected.
I have the following scrollToTop component following this github question: https://github.com/ReactTraining/react-router/issues/6665
Here is the component:
import React from "react";
import { useEffect } from "react";
import { useLocation, withRouter } from "react-router-dom";
const ScrollToTop: React.FC = (props: any) => {
const { pathname } = useLocation();
useEffect(() => {
window.scrollTo(0, 0);
}, [pathname]);
return props.children;
};
export default withRouter(ScrollToTop);
here is my App Component:
function App() {
const dispatch = useDispatch();
// fetches necessary configurations for elements img size etc.
const configMbdApiState = useSelector(
(state: RootStore) => state.postApiConfigurationReducer
);
const storeSearchValueHandlerState = useSelector(
(state: RootStore) => state.searchValueFromInputHandlerR
);
useEffect(() => {
dispatch(
postMDBConfigurationApi(
`https://api.themoviedb.org/3/configuration?api_key=${configMbdApiState.apiKey}`
)
);
dispatch(
postMoviesGenresFetchResponse(
`https://api.themoviedb.org/3/genre/movie/list?api_key=${configMbdApiState.apiKey}`
)
);
dispatch(
postTvshowsGenresFetchResponse(
`https://api.themoviedb.org/3/genre/tv/list?api_key=${configMbdApiState.apiKey}`
)
);
}, []);
// if user clicks outside the instant results div, it removes the div from the UI
const resetsUserSearchHandler = () => {
if (storeSearchValueHandlerState.userSearchValue.length > 0) {
dispatch(storesUserSearchValueHandler(""));
}
};
return (
<BrowserRouter>
<div className="App" onClick={resetsUserSearchHandler}>
<Switch>
<ScrollToTop>
<Route path="/" exact component={WelcomePage} />
<Route path="/home" component={Home} />
<Route
path="/details/movie/:title"
component={SingleMovieDetails}
/>
<Route path="/details/tv/:title" component={TvShowDetails} />
<Route path="/details/actor/:name" component={ActorDetails} />
<Route path="/results" component={ResultsPage} />
</ScrollToTop>
</Switch>
</div>
</BrowserRouter>
);
}
export default App;
Things I have tried:
Console logged the pathname to see if it changes in every render cycle and it does.
I have tried to move scrollToTop and use it directly on the components and it doesn't work either.
At the moment I'm using "any" for the props type in the scroll component. Could this be the problem ?
I'm using NavLink from route-react-dom to direct to other paths, so I don't really know what the issue could be.