enter code here
Compiled with problems:X
ERROR
[eslint]
src\Components\menu.js
Line 20:25: React Hook "useTranslation" is called in function "menu" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use" react-hooks/rules-of-hooks
Line 20:25: 'useTranslation' is not defined no-undef
Search for the keywords to learn more about each error.
import { NavLink } from 'react-router-dom';
import { FaBeer } from 'react-icons/fa';
import { RiStore2Line, RiApps2Line, RiWallet3Line, RiPulseLine } from "react-icons/ri";
import { FaUsersCog } from "react-icons/fa";
import './menu.scss'
import { BsCashStack,BsCreditCard2Back } from "react-icons/bs";
// get url path and set active class
const active = (path) => {
if (path in window.location.pathname) {
return 'active';
}
return '';
}
const menu = () => {
const { t, i18n } = useTranslation();
return <div className="menuP">
<div className="menu">
<NavLink to={'/admin/dashboard'} className={active+' dashboard'}>
<RiStore2Line size={28} /> <span>dashboard</span>
</NavLink>
<NavLink to={'/admin/project'} className={active+' project'}>
<RiWallet3Line size={28} /> <span>project</span>
</NavLink>
<NavLink to={'/admin/category'} className={active+' category'}>
<RiApps2Line size={28} /> <span>category</span>
</NavLink>
<NavLink to={'/admin/user'} className={active+' user'}>
<FaUsersCog size={28} /> <span>users</span>
</NavLink>
</div>
</div>
}
export default menu;
header
import './Header.scss'
import { NavLink } from 'react-router-dom';
import React, { useContext } from 'react';
import { GoogleLogout } from 'react-google-login';
import { ThemeContext } from '../App';
import { BsCashStack,BsCreditCard2Back } from "react-icons/bs";
import { useTranslation } from "react-i18next";
const Header = () => {
const Theme = useContext(ThemeContext);
const clientId = "401-yb.apps.googleusercontent.com";
// logout function
const logout = () => {
Theme.setUser(null);
localStorage.removeItem('user');
}
const { t, i18n } = useTranslation();
const changeLanguage = (lng) => {
i18n.changeLanguage(lng);
}
return (
<header>
<NavLink to={'/'} className="logo">
Shop
</NavLink>
<div className="menu">
<nav>
<button className="btn btn-primary" onClick={() => changeLanguage('en')}>English</button>
<button className="btn btn-primary" onClick={() => changeLanguage('ar')}>Arabic</button>
<div className="fext">
{
// if user is admin show admin menu
Theme.user != null && Theme.user.isAdmin === true ?
<div className="admin">
<NavLink to={'/admin/dashboard'} className='dashboard'><span>✏</span> <p>{t("dashboard")}</p></NavLink>
<NavLink to={'/admin/bill'} className='bill'><span>✏</span> <p>{t('bill')}</p></NavLink>
<NavLink to={'/admin/customer'}><span><BsCreditCard2Back/></span> <p>{t('customer')}</p></NavLink>
<NavLink to={'/casher'}><span><BsCashStack/></span> <p>{t('cashier')}</p></NavLink>
</div>
: null
}
<NavLink to={'/cart'}> <img src="/cart.png" alt="" /> <span className='cartN'>{Theme.cart.reduce((total, item) => total + item.quantity, 0)}</span></NavLink>
</div></nav>
</div>
</header>
)
}
export default Header
Related
In my App I have a HeaderLogo component, with <h1> containing animation (inside its head-main class). I would like to re-render this component to trigger animation, after onclick event in <NavLink>.
<NavLink> is inside DropdownMenu, which is inside MainNavi.
HeaderLogo
const HeaderLogo = () => {
return (
<header>
<h1 className="head-main">learning curve</h1>
</header>
)
}
export default HeaderLogo
Dropdown Menu
import { MenuItemContentSchool } from "./sub-components/MenuItemContentSchool"
import { useState } from "react";
import { NavLink } from "react-router-dom";
const DropdownMenu2 = () => {
const [click, setClick] = useState("");
const handleClick = () => {
setClick("hide-menu");
}
return (
<div className={`dropdown-holder-us ${click}`}>
{MenuItemContentSchool.map((item) => {
return (
<NavLink
to={item.link}
className='d-content-us'
onClick={handleClick}
key={item.title}
>
{item.title}
</NavLink>
)
} )}
</div>
)
}
export default DropdownMenu2
App
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import HeaderLogo from "./components/HeaderLogo";
import NaviMain from "./components/NaviMain";
function App() {
return (
<Router>
<div className="App">
<HeaderLogo />
<NaviMain />
<Routes>
//...
</Routes>
</div>
</Router>
);
}
export default App;
NaviMain
import DropdownMenu2 from "./DropdownMenu2";
const NaviMain = () => {
return (
<nav>
<ul className="nav-main">
<li className="nav-main__button">
<a>school</a>
<DropdownMenu2 />
</li>
</ul>
</nav>
)
}
export default NaviMain
I do not know whether this will work or not but u can try the following solution:
set an id:
<h1 id="testing" className="head-main">learning curve</h1>
Change
const handleClick = () => {
setClick("hide-menu");
}
to
const handleClick = () => {
setClick("hide-menu");
let element = document.getElementById('#testing').
element.classList.remove("head-main");
element.classList.add("head-main");
}
Please let me know whether this solution works or not.
I am using Jest and react testing library for TDD in NextJS, In the nav component I am using the code
<li className={router.pathname.startsWith('/settings/employeetypes') ? "active-link" : ""}>
<a className="dropdown-item" href="#">Employee Type</a>
</li>
Nav component is being used in Home Component.
and test file is :
import React from 'react'
import { render, screen } from '#testing-library/react'
import * as nextRouter from 'next/router';
import '#testing-library/jest-dom'
nextRouter.useRouter = jest.fn();
nextRouter.useRouter.mockImplementation(() => ({ route: '/' }));
import Home from '../pages/index'
describe('Home', () => {
it('Home Page renders a NavBar', () => {
render(<Home />)
expect(screen.getByText(/live/i)).toBeInTheDocument();
})
it('Homepage should display app-wrapper class',() => {
const { container } = render(<Home />)
expect(container.getElementsByClassName('app-wrapper').length).toBe(1);
})
it('Homepage should display map',() => {
const { container } = render(<Home />)
expect(container.firstChild).toMatchSnapshot();
})
})
The code of Home Component is :
import axios from 'axios'
import NavBar from '#/components/NavBar'
import { useRef, useEffect } from 'react'
import { loadModules } from 'esri-loader'
export default function Home({...props}) {
useEffect(() => {
// some stuff there
})
return (
<div id="home-container">
<NavBar />
....
....
</div>
}
export async function getServerSideProps(context) {
... // Call API for get data for Home Component
}
Code of NavBar Component:
import Link from "next/link";
import { useRouter } from "next/router";
const NavBar = ({...props}) => {
const router = useRouter();
return (
<ul className="dropdown-menu" aria-labelledby="navbarDropdown">
<li className={router.pathname == "/" ? "active-link nav-item" : "nav-item"}>
<Link href="/">
<a className="nav-link">
<span className="nav-icon">
<img src="/icons/dashboard.png" />
</span>
<span className="nav-link-text">Live View</span>
</a>
</Link>
</li>
<li className={router.pathname.startsWith('/settings/locations') ? "active-link" : ""}>
<Link href="/settings/locations">
<a className="dropdown-item">Locations</a>
</Link>
</li>
</ul>
)
}
You can mock useRouter() to return an object like {pathname: "/settings/locations"}. Then router.pathname is no longer undefined and has a startsWith() method.
You just have to modify an existing line in your test file:
nextRouter.useRouter.mockImplementation(() => ({ route: '/', pathname: '/' })); // or which pathname you want to test
I am successfully able to do a Google login. After the successful login routing to next page and getting the sign-out button there.
For that I have created a reusable header component and using it. From that page wanted to route other page with sign out button present in the header component (Actually want to display the sign out button all over the application until the user purposefully signed out).
How can I achieve this?
Created
Login page
Google login page imported that to header and using header in all the pages.
login.js
import React, { useState } from 'react';
import './login.css'
import { Link,useHistory } from 'react-router-dom';
import GoogleLogin from '../login/GoogleLogin.jsx'
function Login(props) {
return (
<div className="login__container">
<GoogleLogin className="g-signin" />
</div>
);
}
export default Login;
googleLogin.js
import React, { useState } from 'react';
import { GoogleLogin, GoogleLogout } from 'react-google-login';
import { useHistory } from 'react-router-dom';
const clientId = "Your client ID";
function Googlelogin(props) {
const [showloginButton, setShowloginButton] = useState(true);
const [showlogoutButton, setShowlogoutButton] = useState(false);
const history = useHistory();
const onLoginSuccess = (res) => {
console.log('Login Success:', res.profileObj);
setShowloginButton(false);
setShowlogoutButton(true);
history.push("/pagination");
};
const onLoginFailure = (res) => {
console.log('Login Failed:', res);
};
const onSignoutSuccess = () => {
alert("You have been logged out successfully");
history.push("/");
};
return (
<div>
{ showloginButton ?
<GoogleLogin
clientId={clientId}
buttonText="Sign In"
onSuccess={onLoginSuccess}
onFailure={onLoginFailure}
cookiePolicy={'single_host_origin'}
isSignedIn={true}
/> : null}
{ showlogoutButton ?
<GoogleLogout
clientId={clientId}
buttonText="Sign Out"
onLogoutSuccess={onSignoutSuccess}
>
</GoogleLogout> : null
}
</div>
);
}
export default Googlelogin;
header.js
import React,{useState} from 'react';
import GoogleLogin from '../login/GoogleLogin.jsx';
import Nav from 'react-bootstrap/Nav';
import './Header.css'
import { Link,useHistory } from 'react-router-dom';
function Header() {
const history = useHistory();
const handleMoreInfo = () =>{
history.push("/contacts");
}
return (
<div>
<nav class="navbar navbar-light navbar-expand-md bg-faded justify-content-center">
<Link to="/contacts">Contacts</Link>
<div class="navbar-collapse w-100" id="collapsingNavbar3">
<ul class="nav navbar-nav ml-auto w-100 justify-content-end">
<GoogleLogin />
<li class="nav-item">
<a class="nav-link" href="#" onClick={handleMoreInfo}>More Info</a>
</li>
</ul>
</div>
</nav>
</div>
);
}
export default Header;
I'm trying to test hoc wrapped component.
The component calls an apollo query inside.
const Header: React.FC<IProps> = ({}) => {
const { data, loading } = useMeQuery();
return (
<>
{!data?.me.verified && (
<div className="bg-red-500 p-3 text-center text-sm text-white font-bold">
<span>Please verify your email</span>
</div>
)}
<header className="py-4">
<div className="w-full px-5 xl:px-0 max-w-screen-xl bg-yellow-500 mx-auto">
<Image
src="/pineapple.png"
alt="pineapple-logo"
width="64"
height="64"
/>
{data ? (
<NextLink href="edit-profile">
<Link>
<span className="text-sm">
<FontAwesomeIcon className="text-xl" icon={faUser} />
{data?.me.email}
</span>
</Link>
</NextLink>
) : (
<div>Login</div>
)}
</div>
</header>
</>
);
};
export { Header as PureHeader };
export default withApollo()(Header);
import { render, waitFor } from "#testing-library/react";
import React from "react";
import Header, { PureHeader } from "../../src/components/Header";
import { ApolloProvider } from "#apollo/client";
import { createMockClient } from "mock-apollo-client";
import { MockedProvider } from "#apollo/client/testing";
import withApolloMocked from "../../src/apollo/__mock__/withApolloMocked";
describe("<Header />", () => {
it("renders ok", async () => {
const mockedClient = createMockClient();
render(
<ApolloProvider client={mockedClient}>
<PureHeader />
</ApolloProvider>
);
});
});
Even if I imported Pure Component without hoc, I get the same error when running the test.
However, if remove the hoc and export default Header (which is a pure component), it then passes the test... ;;;
import React from "react";
import Image from "next/image";
import { useMeQuery } from "../generated/graphql";
import { FontAwesomeIcon } from "#fortawesome/react-fontawesome";
import { faUser } from "#fortawesome/free-solid-svg-icons";
import NextLink from "next/link";
import { Link } from "#chakra-ui/react";
import withApollo from "../apollo/withApollo";
interface IProps {}
const Header: React.FC<IProps> = ({}) => {
const { data, loading } = useMeQuery();
return (
<>
{!data?.me.verified && (
<div className="bg-red-500 p-3 text-center text-sm text-white font-bold">
<span>Please verify your email</span>
</div>
)}
<header className="py-4">
<div className="w-full px-5 xl:px-0 max-w-screen-xl bg-yellow-500 mx-auto">
<Image
src="/pineapple.png"
alt="pineapple-logo"
width="64"
height="64"
/>
{data ? (
<NextLink href="edit-profile">
<Link>
<span className="text-sm">
<FontAwesomeIcon className="text-xl" icon={faUser} />
{data?.me.email}
</span>
</Link>
</NextLink>
) : (
<div>Login</div>
)}
</div>
</header>
</>
);
};
// export { Header as PureHeader };
// export default withApollo()(Header);
export default Header;
import { render, waitFor } from "#testing-library/react";
import React from "react";
// import Header, { PureHeader } from "../../src/components/Header";
import Header from "../../src/components/Header";
import { ApolloProvider } from "#apollo/client";
import { createMockClient } from "mock-apollo-client";
import { MockedProvider } from "#apollo/client/testing";
import withApolloMocked from "../../src/apollo/__mock__/withApolloMocked";
describe("<Header />", () => {
it("renders ok", async () => {
const mockedClient = createMockClient();
render(
<ApolloProvider client={mockedClient}>
<Header />
</ApolloProvider>
);
});
});
Did I miss something? OR Is it just a bug?
I'm not quite sure how to deal with this problem...
First of all, I like to apologize for writing such a long post.I'm new to react and redux and I have created an ecommerce app. After implementing redux, I'm getting this error.
./src/Main.js
36:12-26 './redux/configureStore' does not contain an export named 'ConfigureStore'.
My code:
index.js
import React from "react";
import ReactDOM from "react-dom";
import Main from "./Main";
import "./index.css";
import 'bootstrap/dist/css/bootstrap.css';
import {BrowserRouter} from 'react-router-dom';
ReactDOM.render((
<BrowserRouter>
<Main/>
</BrowserRouter>
)
,
document.getElementById("root")
);
Main.js
import React, { Component } from "react";
import 'bootstrap/dist/css/bootstrap.min.css';
import $ from 'jquery';
import Popper from 'popper.js';
import 'bootstrap/dist/js/bootstrap.bundle.min';
import { Route, Switch, withRouter} from 'react-router-dom';
import Navigation from "./components/topNavigation";
import Footer from "./components/Footer";
import Banner from "./components/Banner";
import PLPMenu from "./components/PLPMenu";
import PDP from "./components/PDP";
import Login from "./components/Login"
import Home from "./components/Home";
import { Provider } from 'react-redux';
import { ConfigureStore } from './redux/configureStore';
import {connect} from 'react-redux';
const mapStateToProps = state =>{
return {
topnavigation: state.topnavigation,
plpmenu: state.plpmenu,
pdpmenu : state.pdpmenu
}
}
const store = ConfigureStore();
class Main extends Component {
render() {
return (
<Provider store={store}>
<div>
<Login />
<Navigation />
<Switch>
<Route exact path="/" component={Home} />
<Route path="/Apparel/:category/:subCategory/:id" component={PLPMenu} />
<Route path="/Apparel/:product/:id" component={PDP} />
<Route path="/login" component={Login} />
<Route path="/Banner" component={Banner} />
<Route path="/Footer" component={Footer} />
</Switch>
</div>
</Provider>
)
}
}
export default withRouter(connect(mapStateToProps)(Main));
topNavigation.js
import React, { Component } from 'react';
import axios from 'axios';
import SubMenu from './subMenu';
class Navigation extends Component {
state = {
mainCategory: []
}
componentDidMount() {
axios.get('http://localhost:3030/topCategory')
.then(res => {
// console.log(res.data.express);
this.setState({
mainCategory: res.data.express.catalogGroupView
})
})
}
render() {
const { mainCategory } = this.props;
return (
<nav className="navbar navbar-expand-lg navbar-dark bg-dark mainmenu">
<a className="navbar-brand" href="#">iFashion</a>
<button className="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarNav">
<ul className="navbar-nav ml-auto">
{
mainCategory.map(navList => (
<li className="nav-item dropdown" key={navList.uniqueID}>
<a className="nav-link dropdown-toggle" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">{navList.name} </a>
<ul className="dropdown-menu secondDropdown" aria-labelledby="navbarDropdown">
<SubMenu below={navList.catalogGroupView} />
</ul>
</li>
))
}
</ul>
</div>
</nav>
)
}
}
export default Navigation;
PLPMenu.js
import React, { Component } from "react";
import { Link } from "react-router-dom";
import Footer from "./Footer";
import axios from "axios";
class PLPMenu extends Component {
state = {
shoeCategory: []
};
fetchData = id => {
axios
.get(`http://localhost:3030/category/` + id)
.then(response => {
console.log(response.data.express.catalogEntryView);
this.setState({
shoeCategory: response.data.express.catalogEntryView
});
})
.catch(err => {
console.log(err);
});
};
componentDidMount() {
let { id } = this.props.match.params;
this.fetchData(id);
}
componentDidUpdate(prevProps) {
let currentId = this.props.match.params.id;
let previousId = prevProps.match.params.id;
if (currentId !== previousId) {
this.fetchData(currentId);
}
}
render() {
const { shoeCategory } = this.props;
const picUrl = "https://149.129.128.3:8443";
return (
<div>
<div className="container">
<div className="row">
{shoeCategory &&
shoeCategory.map(shoeList => {
return (
<div key={shoeList.uniqueID} className="col-md-4">
<h2 key={shoeList.uniqueID} />
<img className="plpImage" src={picUrl + shoeList.thumbnail} />
<Link to={`/Apparel/${shoeList.name}/${shoeList.uniqueID}`}>
<p className="pdp">{shoeList.name}</p>
</Link>
<p>
Price : {shoeList.price[0].value}{" "}
{shoeList.price[0].currency}
</p>
</div>
);
})}
</div>
</div>
<Footer/>
</div>
);
}
}
export default PLPMenu;
PDP.js
import React, { Component } from "react";
import { Route, Link, BrowserRouter } from "react-router-dom";
import axios from "axios";
class PDP extends Component {
state = {
pdpCategory: []
};
fetchData = id => {
axios
.get(`http://localhost:3030/product/` + id)
.then(response => {
console.log(response.data.express.catalogEntryView);
this.setState({ pdpCategory: response.data.express.catalogEntryView });
})
.catch(err => {
console.log(err);
});
};
componentDidUpdate(prevProps) {
let currentId = this.props.match.params.id;
let previousId = prevProps.match.params.id;
if (currentId !== previousId) {
this.fetchData(currentId);
}
}
componentDidMount() {
let { id } = this.props.match.params;
this.fetchData(id);
}
render() {
const { pdpCategory } = this.props;
console.log(pdpCategory);
const picUrl = "https://149.129.128.3:8443";
return (
<div>
<div className="container">
<div className="row">
{pdpCategory &&
pdpCategory.map(pdpList => {
return (
<div key={pdpList.uniqueID} className="col-md-4">
<h2 key={pdpList.uniqueID} />
<img className="pdpImage " src={picUrl + pdpList.thumbnail} />
<p>
Price : {pdpList.price[0].value}{" "}
{pdpList.price[0].currency}
</p>
<p>
Description: {pdpList.longDescription}
</p>
<button type="submit">Add to Cart</button>
</div>
);
})}
</div>
</div>
</div>
);
}
}
export default PDP;
For the redux to implement, I have created a redux folder inside ./src folder and have created two files reducer.js and configureStore.js
import PLPMenu from "../components/PLPMenu";
import PDP from "../components/PDP";
import Navigation from "../components/topNavigation";
export const initialState = {
topnavigation: Navigation,
plpmenu: PLPMenu,
pdpmenu : PDP
};
export const Reducer = ( state = initialState , action) => {
return state;
};
configureStore.js
import { createStore} from 'redux';
import {Reducer, initialState} from './reducer';
export const Configuration = () =>{
const store = createStore(
Reducer,
initialState,
);
return store;
}
I don't know where my code is getting wrong. There is only a single error in the console browser window, which I have shared above. Can anyone please help me on this or given an insight how to perfectly implement a redux store.
change import { ConfigureStore } from './redux/configureStore';
to
import { Configuration } from './redux/configureStore'; in Main.js