When I add my Navigation component to my App.js file the entire site is blank. However, when I add my other components like my Header the page works completely fine. Am I missing something? There are no bugs or errors that are showing up either which is very confusing.
import { useState } from 'react'
import Navigation from './components/Navigation'
import Header from './components/Header';
import Collection from './components/Collection';
function App() {
const [count, setCount] = useState(0)
return (
<div>
<Navigation />
<Header />
<Collection />
</div>
)
}
export default App
import { useState } from "react";
import logo from "../icons/logo.svg";
import CSS from "../styles/Navigation.css";
import hamburger from "../icons/icon-hamburger.svg";
import hamburgerClose from "../icons/icon-close.svg";
import { MobileMenu } from "../components/MobileMenu";
function navigation() {
state = { clicked: false }
handleClick = () => {
this.setState({ clicked: !this.state.clicked })
}
return (
<>
<div className="navigation">
<img className="logo" src={logo} />
<button className="hamburger" onClick={this.handleClick}>
<img className={this.state.clicked ? {hamburger} : {hamburgerClose}}/>
</button>
<div className="navigation-menu">
<ul>
{MobileMenu.map((item, index) => {
return (
<li key={index}>
<a className={item.className} href={item.url}>
{item.title}
</a>
</li>
);
})}
</ul>
</div>
</div>
</>
);
}
export default navigation;
The state could only be used in class components. Using hooks, you can apply state to functional components too. Below code example
import React, { useState } from 'react';
function Example() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}
Related
I am receiving the error Uncaught TypeError: Cannot read properties of null (reading 'scrollIntoView') when trying to click on an item on my Navbar.
It's bit of a tricky issue, but if I load the page from scratch, it will throw the above error. However, if I save the project in VSCode again, it will work perfectly fine until I refresh the page. Is there anyway to correct this issue?
Navbar.jsx:
import { useState } from 'react';
import { Link } from 'react-router-dom';
import '../App.css';
import myAvatar from '../images/avataaars.png';
function Navbar() {
const aboutPage = document.getElementById('about');
const home = document.getElementById('home');
const skills = document.getElementById('skills');
const [navbar, setNavbar] = useState(true);
const handleNavbarToggle = (e) =>{
setNavbar(!navbar);
}
return(
<>
<div className='navbar-container'>
<Link to='/'><img src={myAvatar} className='nav-logo'/></Link>
<ul>
<li onClick={() =>{home.scrollIntoView({behavior: 'smooth'})}}>Home</li>
<li onClick={() =>{aboutPage.scrollIntoView({behavior: 'smooth'})}}>About</li>
<li onClick={() => {skills.scrollIntoView({behavior: 'smooth'})}}>Skills</li>
<li>Projects</li>
<li id='navbar-login-btn'>Login</li>
</ul>
<div className={`navbar-toggle ${navbar ? '' : 'open'}`} onClick={handleNavbarToggle}>
<span></span>
<span></span>
<span></span>
</div>
</div>
<div className={`navbar-header ${navbar ? 'navbar-header-hide' : ''}`}>
<ul>
<Link className='navbar-header-item' to='/'>Home</Link>
<Link className='navbar-header-item' to='/about'>About</Link>
<Link className='navbar-header-item' to='/skills'>Skills</Link>
<Link className='navbar-header-item' to='/projects'>Projects</Link>
<Link className='navbar-header-item' to='/login'>Login</Link>
</ul>
</div>
</>
)
}
export default Navbar;
App.js:
import { useState, useEffect } from 'react';
import { Route, Routes } from 'react-router-dom';
import TextTransition, { presets } from 'react-text-transition';
import './App.css';
import Navbar from './components/Navbar';
import Homepage from './components/Homepage';
import About from './components/About';
import Skills from './components/Skills';
import myAvatar from './images/avataaars.png';
function App() {
return (
<>
<Navbar />
<div className='homepage-container-web'>
<Homepage />
<About />
<Skills />
</div>
<div className='homepage-container-devices'>
<Routes>
<Route path='/' element={<Homepage />} />
<Route path='/about' element={<About />}/>
</Routes>
</div>
</>
);
}
export default App;
About.jsx:
import '../App.css';
function About() {
return(
<>
<div className='about-container' id='about'>
<h2 class='about-title'>A little bit about me...</h2>
<p>Hi, my name is Andrew! I'm 20 years old, and I have <a href='https://www.crohnscolitisfoundation.org/what-is-crohns-disease' target="_blank" style={{color: '#a61bee'}}>Crohn's Disease</a>. Ever since I was 12 years old I have had an interest in technology, software engineering, cybersecurity, firefighting, and cars. I currently work for the Department of Defense and hold a Senior IT Specialist position. I am always looking to learn and improve myself.</p>
</div>
<div className='about-ending-container' />
</>
)
}
export default About;
The issue is that the first time it renders, when you do this
const aboutPage = document.getElementById('about');
const home = document.getElementById('home');
const skills = document.getElementById('skills');
those elements don't exist yet. The simplest solution would be to just change it to
const aboutPage = () => document.getElementById('about');
const home = () => document.getElementById('home');
const skills = () => document.getElementById('skills');
// ...
<li onClick={() =>{home().scrollIntoView({behavior: 'smooth'})}}>Home</li>
<li onClick={() =>{aboutPage().scrollIntoView({behavior: 'smooth'})}}>About</li>
<li onClick={() => {skills().scrollIntoView({behavior: 'smooth'})}}>Skills</li>
so that it does the search at the time of the click. That's not a very "react" way of doing it. But it should "just work".
If you want to do it the "right way", I supposed you'd want to use useRef, and hoist that up to the App. Using just home as an example, and omiting non-relevant code, it would be something like:
function App() {
const homeRef = useRef();
// ...
<Navbar homeRef={homeRef} />
// ...
<Homepage ref={homeRef} />
}
function Navbar({ homeRef }) {
const scrollIntoView = (ref) => {
if (ref.current) {
ref.current.scrollIntoView({behavior: 'smooth'})
}
}
<li onClick={() =>{scrollIntoView(homeRef)}}>Home</li>
}
const Homepage = React.forwardRef((props, ref) => {
return(
<>
<div className='home-container' id='hone' ref={ref} >
//...
</div>
</>
)
})
I have two buttons on my react app's header. One for translating the application to Spanish and the other for English. The problem is that every time I press one of this buttons and update the state, the homepage gets loaded despite the translation is completed correctly. How can I avoid this redirection to the homepage and remain in the current page where the user is at that moment?
App.js, where the IntlProvider gets the language through state triggered by onclick function:
import { MsalProvider } from "#azure/msal-react";
import "bootstrap/dist/css/bootstrap.min.css";
import { IntlProvider } from "react-intl";
import { BrowserRouter } from "react-router-dom";
import "./App.css";
import AppContent from "./AppContent";
import { lang } from "./assets/lang/lang";
import Header from "./pages/common/Header";
import { useState } from "react";
function App({ msalInstance }) {
const [localeLanguage, setLocaleLanguage] = useState("en");
const onChangeLanguage = (lang) => {
setLocaleLanguage(lang);
};
return (
<MsalProvider instance={msalInstance}>
<BrowserRouter>
<IntlProvider
key={localeLanguage}
locale={localeLanguage}
messages={lang[localeLanguage]}
>
<Header onChangeLanguage={onChangeLanguage} />
<AppContent />
</IntlProvider>
</BrowserRouter>
</MsalProvider>
);
}
export default App;
Header.js, where the two buttons are:
import { useIsAuthenticated, useMsal } from "#azure/msal-react";
import { FormattedMessage } from "react-intl";
import { Link } from "react-router-dom";
import logo from "../../assets/img/softwareOne.png";
import { loginRequest } from "../../util/authConfig";
import { useIntl } from "react-intl";
export default function Header(props) {
const isAuthenticated = useIsAuthenticated();
const { instance } = useMsal();
const intl = useIntl();
return (
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<Link className="navbar-brand" to="/">
<img src={logo} className="logo-navbar" alt="" />
</Link>
<div className="collapse navbar-collapse text-center">
<span className="navbar-text">
<FormattedMessage id="well_architected_survey" />
</span>
</div>
<div className="flex">
<button
className="btn btn-secondary"
onClick={() => {
props.onChangeLanguage("es");
}}
value="es"
>
{intl.locale === "es" ? "Español" : "Spanish"}
</button>
<button
className="btn btn-secondary m-3"
onClick={() => {
props.onChangeLanguage("en");
}}
value="en"
>
{intl.locale === "en" ? "English" : "Inglés"}
</button>
</div>
<div>
<button
className="btn btn-outline-secondary logout-header"
onClick={() =>
isAuthenticated
? instance.logoutRedirect({ postLogoutRedirectUri: "/" })
: instance.loginRedirect(loginRequest)
}
>
<FormattedMessage
id={isAuthenticated ? "logout_button" : "login_button"}
/>
</button>
</div>
</nav>
);
}
I see that the localeLanguage state is used as a React key on the IntlProvider component. When the key value changes this will necessarily remount that component and its entire React subtree (which may very well include any initial mounting effects in any rendered children components). I don't see a point of using a React key here though so it's likely safe to remove it.
function App({ msalInstance }) {
const [localeLanguage, setLocaleLanguage] = useState("en");
const onChangeLanguage = (lang) => {
setLocaleLanguage(lang);
};
return (
<MsalProvider instance={msalInstance}>
<BrowserRouter>
<IntlProvider // <-- remove key prop
locale={localeLanguage}
messages={lang[localeLanguage]}
>
<Header onChangeLanguage={onChangeLanguage} />
<AppContent />
</IntlProvider>
</BrowserRouter>
</MsalProvider>
);
}
I am trying when I click on a modal to have an animation to show the modal but I don't achieve to do that using Tailwind and react.
Here is my code :
import React, { useState, useCallback } from "react";
import ReactDOM from "react-dom";
import Wrapper from "./Wrapper";
import Input from "./Input";
import "./styles.css";
import Button from "./Button";
import Modal from "./Modal";
function App() {
const [showModal, setShowModal] = useState(false);
const handleShowModal = useCallback(() => {
setShowModal(!showModal);
}, [showModal]);
const handleCloseModal = useCallback(() => {
setShowModal(false);
}, []);
return (
<div className="p-4">
<h1 className="text-red-500 text-center">PlayGround</h1>
<Wrapper className="p-2">
<Input />
</Wrapper>
<Wrapper className="p-2">
<Button onClick={handleShowModal}>Show Modal</Button>
{showModal && <Modal onCancel={handleCloseModal} />}
</Wrapper>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
And you can see my full code here :
my full project
I would like something like that :
the goal
How can I do that ?
Thank you very much !
I recommend using headless ui
you can use like this
import { Transition } from '#headlessui/react'
import { useState } from 'react'
function MyComponent() {
const [isShowing, setIsShowing] = useState(false)
return (
<>
<button onClick={() => setIsShowing((isShowing) => !isShowing)}>
Toggle
</button>
<Transition
show={isShowing}
enter="transition-opacity duration-75"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition-opacity duration-150"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
I will fade in and out
</Transition>
</>
)
}
As the title says my navbar is not changing the fragments after updating the state. I have no idea how to refresh it and other ideas seems to not work for me. I have tried to change the statements.
All i want to do is, after a user logs in successfully the state changes to true and the navbar updates with the corrent components. Thank you !
Home.js
import React, { useEffect } from 'react'
function Home() {
useEffect(()=>{
if(!localStorage.getItem("loggedIn")){
localStorage.setItem("loggedIn",false);
}
},[]);
return (
<div>
Home
</div>
)
}
export default Home
Login.js
import React from 'react';
import './Login.css';
import Axios from 'axios';
import { useEffect, useState } from "react";
import {useHistory} from 'react-router-dom';
function Login() {
const[username,setUsername] = useState('');
const[password,setPassword] = useState('');
const[errorMessage,setErrorMessage] = useState('');
let history = useHistory();
const login = () =>{
console.log(username);
Axios.post("http://localhost:3001/user/login",{username: username,password: password}).then((response) => {
//console.log(response);
if(response.data.loggedIn){
localStorage.setItem("loggedIn",true);
localStorage.setItem("username",response.data.username);
history.push('/');
}else{
setErrorMessage(response.data.message);
}
});
};
return (
<div className="Login">
<h1>Login to your BugTrack account !</h1>
<div className="LoginForm">
<input type="text" placeholder="USERNAME"
onChange={(event)=>{setUsername(event.target.value)}}/>
<input type="password" placeholder="PASSWORD"
onChange={(event)=>{setPassword(event.target.value)}}/>
<button onClick={login}>Login to you account</button>
<h1 style={{color: "red"}}>{errorMessage}</h1>
</div>
</div>
);
}
export default Login
Navbar.js
import React, { useEffect, useState, Component, Fragment } from 'react';
import './Navbar.css';
function Navbar() {
const [loggedIn, setLoggedIn] = useState(false);
useEffect(()=> {
setLoggedIn(localStorage.getItem("loggedIn"));
},[localStorage.getItem("loggedIn")]);
return (
<div className="Navbar">
Home
{!loggedIn ? (
<Fragment>
Profile
</Fragment>
):(
<Fragment>
Register
Login
</Fragment>
)}
</div>
);
}
export default Navbar;
You want to to use localStorage as a useEffect dependency which isn't supports for React to rerender/update the component. Check this: useEffect do not listen for localStorage - it's like duplicate of your question.
I am making a simple react counter, where on click INC button the value should change the value inside h1. But it is not working.
My code in App.js:
import React from "react";
import "./styles.css";
export default function App() {
let count = 0;
function handleInc () {
return count++;
}
return (
<>
<div>
<h1>{count}</h1>
<div className='container'>
<button onClick={handleInc}>INC</button>
<button>DEC</button>
<button>RESET</button>
</div>
</div>
</>
);
}
Can you please tell me what the error is?
You need to useState! On each click, this method will tell react to re-render this component and any children, thus displaying the updated counter to the dom.
import React, { useState } from "react";
import "./styles.css";
export default function App() {
let [count, setCount] = useState(0);
function handleInc () {
return setCount(count + 1);
}
return (
<>
<div>
<h1>{count}</h1>
<div className='container'>
<button onClick={handleInc}>INC</button>
<button>DEC</button>
<button>RESET</button>
</div>
</div>
</>
);
}