Still learning Java and functions. Was writing some code but got stumped.
In my App.js class, I have a line of code in the return statement as follows:
<Toolbar drawerClickHandler ={props.drawerToggleClickHandler}/>
In my Toolbar class, it would activate via a "click" as follows:
<DrawerToggleButton click={props.drawerClickHandler}/>
Which would last be connected to another class DrawerToggleButton in the following code:
<button className="toggle-button" onClick={props.click}>
The Toolbas class and the DrawerToggleButton have no issues with passing but props.drawerToggleClickHandler does not work, says "Unresolved variable drawerToggleClickHandler".
How can I fix this? Full code below:
App.js:
import React, { useState, useEffect } from "react";
// import logo from './logo.svg';
import './App.css';
import Routes from "./Routes";
import { Auth } from "aws-amplify";
import { Link, withRouter } from "react-router-dom";
// import { Navbar } from "react-bootstrap";
import Toolbar from './components/Toolbar/Toolbar';
import SideDrawer from './components/SideDrawer/SideDrawer';
import Backdrop from './components/Backdrop/Backdrop';
function App(props) {
const [isAuthenticated, userHasAuthenticated] = useState(false);
const [isAuthenticating, setIsAuthenticating] = useState(true);
const [sideDrawerOpen, setIsSideDrawerOpen] = useState(false);
useEffect(() => {
onLoad();
}, []);
async function onLoad() {
try {
await Auth.currentSession();
userHasAuthenticated(true);
}
catch(e) {
if (e !== 'No current user') {
alert(e);
}
}
setIsAuthenticating(false);
}
function handleLogout() {
userHasAuthenticated(false);
props.history.push("/login");
}
function drawerToggleClickHandler(){
if(sideDrawerOpen){
return {setIsSideDrawerOpen: false};
}
else{
return {setIsSideDrawerOpen: true};
}
}
let sideDrawer;
let backdrop;
let toolBar;
if(userHasAuthenticated === true){
toolBar = <Toolbar drawerClickHandler ={props.drawerToggleClickHandler}/>
}
if (userHasAuthenticated === true && sideDrawerOpen === true){
sideDrawer = <SideDrawer/>;
backdrop = <Backdrop/>
}
return (
<div className="App container" style={{height: '100%'}}>
{toolBar}
{sideDrawer}
{backdrop}
{/*<Toolbar/>*/}
{/*<SideDrawer/>*/}
{/*<Backdrop/>*/}
<Routes appProps={{ isAuthenticated, userHasAuthenticated }} />
</div>
);
}
export default withRouter(App);
Toolbar.js:
import React from 'react';
import './Toolbar.css';
import DrawerToggleButton from '../SideDrawer/DrawerToggleButton'
import '../SideDrawer/DrawerToggleButton';
import sideDrawer from "../SideDrawer/SideDrawer";
const toolbar = props =>(
<header className="toolbar">
<nav className="toolbar_navigation">
<div>
<DrawerToggleButton click={props.drawerClickHandler}/>
</div>
<div className="toolbar_logo">Kleen Portal</div>
<div className="spacer" />
<div className="toolbar_navigation-items">
<ul>
<li>Logout</li>
</ul>
</div>
</nav>
</header>
);
export default toolbar;
DrawerToggleButton.js:
import React from 'react';
import './DrawerToggleButton.css'
const drawerToggleButton = props => (
<button className="toggle-button" onClick={props.click}>
<div className="toggle-button_line" />
<div className="toggle-button_line" />
<div className="toggle-button_line" />
</button>
);
export default drawerToggleButton;
You're not changing state: you'd need to change your function to this (and i'd suggest renaming setState to setsIsSideDrawerOpen)
function drawerToggleClickHandler(){
if(sideDrawerOpen){
setState(false)
}
else{
setState(true)
}
}
Change
toolBar = <Toolbar drawerClickHandler ={props.drawerToggleClickHandler}/>
to
toolBar = <Toolbar drawerClickHandler ={drawerToggleClickHandler}/>
drawerToggleClickHandler is not a prop
[Also app.js is not a class it's a functional component]
to answer your second comment question I wouldn't event assign your component to a variable, just do it inline:
<div className="App container" style={{height: '100%'}}>
{userHasAuthenticated && <Toolbar drawerClickHandler =props.drawerToggleClickHandler}/>
}
...
Related
This question might be simple to most web developers but I am pretty new and cannot figure out the way to put a settimeout function on what I would like to show on a page. below is the example of the code I would like to add a timeout for.
import React from "react";
function Navbar() {
return (
<div className="navbar">
<h4>
Contact
</h4>
<h4>About Me</h4>
</div>
);
}
export default Navbar;
and here is my app.jsx which then will be exported to be used in index.js . What I want is to have lets say 5s delay before my Navbar function shows.
import React, { useEffect } from "react";
import Navbar from "./Navbar";
import Contact from "./Contact";
function App() {
return (
<div>
<Navbar />
<Contact />
</div>
);
}
export default App;
You can add setTimeout in your App Component. It should look like this:
import React, { useState, useEffect } from "react";
import Navbar from "./Navbar";
import Contact from "./Contact";
function App() {
const [showNavBar, setShowNavBar] = useState(false);
useEffect(() => {
const timer = setTimeout(() => {
setShowNavBar(true);
}, 5000);
return () => clearTimeout(timer);
}, [])
return (
<div>
{showNavBar ? <Navbar /> : null}
<Contact />
</div>
);
}
export default App;
your can add a state 'loading' and add useEffect hook and then use setTimeout there and change the loading state to false after 5seconds. in return section all you need to do is check if loading is false you show the otherwise it will show nothing.
import React, { useEffect, useState } from "react";
import Navbar from "./Navbar";
import Contact from "./Contact";
function App() {
const [loading, setLoading] = useState(true);
useEffect(() => {
setTimeout(() => {
setLoading(false);
}, 5000);
}, [])
return (
<div>
{!loading && <Navbar /> }
<Contact />
</div>
);
}
export default App;
I recently started working with React, and I'm trying to understand why my context.js is giving me so much trouble. Admittedly I'm not great with JavaScript to start, so I'd truly appreciate any insight.
Thank you, code and the error that it generates:
import React, { useState, useContext } from 'react';
const AppContext = React.createContext(undefined, undefined);
const AppProvider = ({ children }) => {
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
const openSidebar = () => {
setIsSidebarOpen(true);
};
const closeSidebar = () => {
setIsSidebarOpen(false);
};
const toggle = () => {
if (isSidebarOpen) {
closeSidebar();
} else {
openSidebar();
}
};
return (
<AppContext.Provider
value={{
isSidebarOpen,
openSidebar,
closeSidebar,
toggle
}}
>
{children}
</AppContext.Provider>
);
};
export const useGlobalContext = () => {
return useContext(AppContext);
};
export { AppContext, AppProvider };
Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
You might have mismatching versions of React and the renderer (such as React DOM)
You might be breaking the Rules of Hooks
You might have more than one copy of React in the same app
Thank you again for taking the time to look!
EDIT: Sidebar App Added for context (double entendre!)
import React from 'react';
import logo from './logo.svg'
import {links} from './data'
import {FaTimes} from 'react-icons/fa'
import { useGlobalContext } from "./context";
const Sidebar = () => {
const { toggle, isSidebarOpen } = useGlobalContext();
return (
<aside className={`${isSidebarOpen ? 'sidebar show-sidebar' : 'sidebar'}`}>
<div className='sidebar-header'>
<img src={logo} className='logo' alt='NavTask Management'/>
<button className='close-btn' onClick={toggle}>
<FaTimes />
</button>
</div>
<ul className='links'>
{links.map((link) => {
const { id, url, text, icon } = link;
return (
<li key={id}>
<a href={url}>
{icon}
{text}
</a>
</li>
);
})}
</ul>
</aside>
);
};
export default Sidebar;
I am trying to create a background theme which will switch on onClick. On onClick it must change the background color of body in react app. I've managed to implement useContext, and now it toggles and changes the list items color in Header component. How to set it to body as well? Any help will be appreciated.
Here is my useContext color component
import React from 'react'
export const themes = {
light: {
foreground: '#ffffff',
},
blue: {
foreground: 'blue',
},
}
export default React.createContext({
theme: themes.light,
switchTheme: () => {},
})
onClick Button component
import React, { useContext } from 'react'
import ThemeContext from './context'
import './ThemedButton.scss'
const ThemedButton = () => {
const { switchTheme } = useContext(ThemeContext)
return (
<>
<button className="btn" onClick={switchTheme}>
Switch
</button>
</>
)
}
export default ThemedButton
App.js
import React, { useState } from 'react'
import SearchBar from './components/SearchBar';
import useCountries from './Hooks/useCountries';
import MainTable from './components/MainTable';
import ThemeButton from './useContext/ThemedButton';
import ThemeContext from './useContext/context';
import { searchProps } from './types';
import { themes } from './useContext/context';
import Routes from './Routes';
import './App.scss'
export default function App() {
const [search, setSearch] = useState('')
const [data] = useCountries(search)
const [context, setContext] = useState({
theme: themes.light,
switchTheme: () => {
setContext((current) => ({
...current,
theme: current.theme === themes.light ? themes.blue : themes.light,
}))
},
})
const handleChange: React.ReactEventHandler<HTMLInputElement> = (e): void => {
setSearch(e.currentTarget.value)
}
return (
<div className="App">
<SearchBar handleChange={handleChange} search={search as searchProps} />
<ThemeContext.Provider value={context}>
<ThemeButton />
<MainTable countries={data} />
</ThemeContext.Provider>
<Routes />
</div>
)
}
Header component
import React, { useContext } from 'react'
import ThemeContext from '../../useContext/context'
import './Header.scss'
export default function Header() {
const { theme } = useContext(ThemeContext)
return (
<div className="header">
<ul className="HeadtableRow" style={{ color: theme.foreground }}> // here it's set to change list items color
<li>Flag</li>
<li>Name</li>
<li>Language</li>
<li>Population</li>
<li>Region</li>
</ul>
</div>
)
}
If you want to change your body tag in your application you need to modify DOM and you can add this code to your Header.js (or any other file under your context) file:
useEffect(() => {
const body = document.getElementsByTagName("body");
body[0].style.backgroundColor = theme.foreground
},[])
*** Don't forget to import useEffect
*** Inline style like below is a better approach than modifying DOM directly
<div className="App" style={{backgroundColor: context.theme.foreground}}>
//For under context files just use theme.foreground
<SearchBar handleChange={handleChange} search={search as searchProps} />
<ThemeContext.Provider value={context}>
<ThemeButton />
<MainTable countries={data} />
</ThemeContext.Provider>
<Routes />
</div>
I have a java script file called Toolbar.js in which I am trying to call a function that is in my App.js file as the following:
<DrawerToggleButton click={props.drawerClickHandler}/>
The above does not work, it shows "Unresolved variable drawerClickHandler" which I assume means that Toolbar.js can not see the functions in App.js. I have tried this without using props with no results. How can I get this to work?
Also just want to state the program will build and run with no errors, just that the button I am trying to map the function to, does nothing when I click it.
Code below:
Toolbar.js:
import React from 'react';
import './Toolbar.css';
import DrawerToggleButton from '../SideDrawer/DrawerToggleButton'
import '../SideDrawer/DrawerToggleButton';
import sideDrawer from "../SideDrawer/SideDrawer";
const toolbar = props =>(
<header className="toolbar">
<nav className="toolbar_navigation">
<div>
<DrawerToggleButton click={props.drawerClickHandler}/>
</div>
<div className="toolbar_logo">Kleen Portal</div>
<div className="spacer" />
<div className="toolbar_navigation-items">
<ul>
<li>Logout</li>
</ul>
</div>
</nav>
</header>
);
export default toolbar;
App.js:
import React, { useState, useEffect } from "react";
// import logo from './logo.svg';
import './App.css';
import Routes from "./Routes";
import { Auth } from "aws-amplify";
import { Link, withRouter } from "react-router-dom";
// import { Navbar } from "react-bootstrap";
import Toolbar from './components/Toolbar/Toolbar';
import SideDrawer from './components/SideDrawer/SideDrawer';
import Backdrop from './components/Backdrop/Backdrop';
function App(props) {
const [isAuthenticated, setIsAuthenticated] = useState(false);
const [isAuthenticating, setIsAuthenticating] = useState(true);
const [sideDrawerOpen, setIsSideDrawerOpen] = useState(false);
useEffect(() => {
onLoad();
}, [isAuthenticating, isAuthenticated]);
async function onLoad() {
try {
await Auth.currentSession();
setIsAuthenticated(true);
props.history.push("/dashboard");
}
catch(e) {
alert(e);
}
setIsAuthenticating(false);
}
function handleLogout() {
setIsAuthenticated(false);
props.history.push("/login");
}
function drawerToggleClickHandler(){
setIsSideDrawerOpen(!sideDrawerOpen)
}
let sideDrawer;
let backdrop;
let toolBar;
if(isAuthenticated){
toolBar = (
<Toolbar
handleLogout={handleLogout}
drawerClickHandler ={drawerToggleClickHandler}
/>
)
}
if (isAuthenticated && sideDrawerOpen){
sideDrawer = <SideDrawer/>;
backdrop = <Backdrop/>
}
return (
<div className="App container" style={{height: '100%'}}>
{toolBar}
{sideDrawer}
{backdrop}
{/*<Toolbar/>*/}
{/*<SideDrawer/>*/}
{/*<Backdrop/>*/}
<Routes appProps={{ isAuthenticated, setIsAuthenticated }} />
</div>
);
}
export default withRouter(App);
DrawerToggleButton.js:
import React from 'react';
import './DrawerToggleButton.css'
const drawerToggleButton = props => (
<button className="toggle-button" onClick={props.click}>
<div className="toggle-button_line" />
<div className="toggle-button_line" />
<div className="toggle-button_line" />
</button>
);
export default drawerToggleButton;
I have been trying to use React-paginate library for pagination, however, the buttons formed by it is not clickable,i don't understand what i am doing wrong
And there are no example given, or no question asked
What would be the correct way of using this pagination
Here is the code of my App.js
import React, { Component } from 'react';
import './App.css';
import Navbar from '../src/components/navbar/navbar'
import SearchIt from '../src/components/searchField/search'
import Container from 'react-bootstrap/Container'
import Card from '../src/components/cards/cards'
import Axios from 'axios'
import Pagination from '../src/components/pagination/paginating'
class App extends Component {
state={
fetchedData:[]
}
componentDidMount(){
Axios.get('http://localhost:3000/1').then((responseData)=>{
//console.log(responseData.data)
this.setState({fetchedData:responseData.data})
}).catch((err)=>{
console.log(err)
})
}
handlePageClicked = data => {
let selected = data.selected;
console.log(selected)
};
render() {
return (
<div className="App">
<Navbar/>
<Container>
<SearchIt/>
<Card data={this.state.fetchedData}/>
<Pagination handlePageClick={this.handlePageClicked}/>
</Container>
</div>
);
}
}
export default App;
And here is the code for paginating.js
import React,{Component} from 'react'
import ReactPaginate from 'react-paginate';
import './paginateStyle.css'
const page = (props)=>{
return(
<ReactPaginate
previousLabel={'previous'}
nextLabel={'next'}
breakLabel={'...'}
breakClassName={'break-me'}
pageCount={10}
marginPagesDisplayed={2}
pageRangeDisplayed={5}
onPageChange={props.handlePageClick}
containerClassName={'pagination'}
subContainerClassName={'pages pagination'}
activeClassName={'active'}
/>
)
}
export default page
These button are not clickable
I did a quick sample and it worked.
import ReactPaginate from 'react-paginate';
const Pagination = (props) => {
return (
<ReactPaginate
previousLabel={'previous'}
nextLabel={'next'}
breakLabel={'...'}
breakClassName={'break-me'}
pageCount={10}
marginPagesDisplayed={2}
pageRangeDisplayed={5}
onPageChange={props.handlePageClick}
containerClassName={'pagination'}
subContainerClassName={'pages pagination'}
activeClassName={'active'}
/>
)
}
class App extends Component {
state = {
selectedPage: 0
}
handlePageClicked = data => {
let selected = data.selected;
this.setState({
selectedPage: selected
})
console.log(selected)
};
render() {
return (
<React.Fragment>
<div>You selected: {this.state.selectedPage}</div>
<div className="App">
<Pagination handlePageClick={this.handlePageClicked} />
</div>
</React.Fragment>
);
}
}
There could be something in paginateStyle.css which is making the Pagination not work properly or some other CSS in your application.
EDIT:
From comments, a ui component with higher z index was over them and was not visible/clickable