How to send functional data to another page in React - reactjs

Playing.js File
import { useState } from "react";
function Playing(){
const [sidebar, setSidebar] = useState(false);
const sidebarFunc = () => {
sidebar ? setSidebar(false) : setSidebar(false);
}
return(
<i onClick={sidebarFunc}>Click</i>
);
}
export default Playing;
Sidebar.js File
function SideBar() {
return (
<div className="">Side Bar</div>
);
}
export default SideBar;
App.js File
import Sidebar from "./Sidebar.js";
import Playing from "./Playing.js";
function App(){
return(
<>
<Sidebar />
<Playing />
</>
);
}
I'm new to react, so try avoiding mistakes by my side. Here i'm trying a way in which the after clicking the Click text, the usestate variable sidebar gets triggered. But the sidebar couldn't be exported so as to get an outcome for Sidebar functional div as <div className="sidebar?"Show":"Hide">Side Bar</div>.
Is there a solution for the same or any other ways it can be done.
Thank you in advance

You can create a state in parent component and then use this state in child component by passing through props and a callback function
App.js File
import Sidebar from "./Sidebar.js";
import Playing from "./Playing.js";
function App(){
const [sidebar, setSidebar] = useState(false);
return(
<>
<Sidebar sidebar={sidebar}/>
<Playing sidebar={sidebar} setSidebar={setSidebar}/>
</>
);
}
Playing.js
import from "react";
function Playing({sidebar,setSidebar}){
const sidebarFunc = () => {
sidebar ? setSidebar(false) : setSidebar(false);
}
return(
<i onClick={sidebarFunc}>Click</i>
);
}
export default Playing;
SideBar.js
function SideBar({sidebar}) {
return (
<div className=`${sidebar?"Show":"Hide"}`>Side Bar</div>
);
}
export default SideBar;

Place the useState() declaration in App.js.
App.js
function App(){
const [sidebar, setSidebar] = useState(false);
return(
<>
<Sidebar sidebar={sidebar}/>
<Playing sidebar={sidebar} setSidebar={(bool) => setSidebar(bool)}/>
</>
);
}
SideBar.js
function SideBar(props) {
return (
<div className={props.sidebar ? "Show" : "Hide"}>Side Bar</div>
);
}
export default SideBar;
Playing.js
function Playing(props){
const sidebarFunc = () => {
props.sidebar ? props.setSidebar(false) : props.setSidebar(false);
}
return(
<i onClick={sidebarFunc()}>Click</i>
);
}
export default Playing;

Related

Re-Rendering component, after click event in different component

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.

how can I call a method that is inside of Component? (I can't pass this method in props)

this seems like a duplicate question but it is not, the examples I have seen explain how to pass a function through props.
I have three components: ComponentA, ComponentB and App (App is the component root). I want to call a function contains in ComponentA using a button that is inside of ComponentB.
import "./styles.css";
import ComponentA from "./componentA";
import ComponentB from "./componentB";
export default function App() {
return (
<div className="App">
<>
<ComponentA>
<ComponentB />
</ComponentA>
</>
</div>
);
}
const ComponentA = ({ children }) => {
const hello = () => {
alert("hello");
//In my real scenario, this method contains a big logic...
};
return (
<>
Component A<div>{children}</div>
</>
);
};
const ComponentB = () => {
const callComponentAFunction = () => {
// I need call "hello()" from ComponentA
};
return (
<>
<button onClick={callComponentAFunction}>
Call function from ComponentA
</button>
</>
);
};
How can I call hello() (function inside of ComponentA) from ComponentB?
this is my live code
You can achieve that in many ways. Pass that function as props from component A.
Working example Modified code
//App.js
import "./styles.css";
import ComponentA from "./componentA";
// import ComponentB from "./componentB";
export default function App() {
return (
<div className="App">
<>
<ComponentA />
</>
</div>
);
}
//Component A
import ComponentB from "./componentB";
const ComponentA = ({ children }) => {
const hello = () => {
alert("hello");
};
return (
<>
Component A<div>{children}</div>
<ComponentB hello={hello} />
</>
);
};
export default ComponentA;
//Component B
const ComponentB = ({ hello }) => {
return (
<>
<button onClick={hello}>Call function from ComponentA</button>
</>
);
};
export default ComponentB;
you can also use the React.Children.map, the example like this: https://codesandbox.io/s/hardcore-ellis-ksgkd?file=/src/componentB.js

How to pass a dynamic value from one component to the other in React

I have a Navbar component with an anchor tag containing an onClick event. On click, a value (navvalue) is passed to the function Testfunction, which is a separate component. I want to import Testfunction into the Content component so that I can have access and display the value coming from Navbar (navvalue). How do I access “navvalue” in Content? This is an assignment in a react course I´m taking. I should use props. I´m not supposed to use either state or React Route since we haven´t reach those topics yet. Thank you for your help!
Here´s my code:
App.js
import "./styles.css";
import React from "react";
import Navbar from "./Navbar";
import Content from "./Content";
import Testfunction from "./Testfunction";
export default function App() {
return (
<div className="App">
<Navbar onPageChange={Testfunction} />
<Content />
</div>
);
}
Navbar.js
import React from "react";
const Navbar = (props) => {
const navvalue = "Nav Value";
return (
<a
className="nav-link active text-uppercase"
aria-current="page"
href="#"
onClick={() => props.onPageChange(navvalue)}
>
{navvalue}
</a>
);
};
export default Navbar;
Testfunction.js
const Testfunction = (navvalue) => {
return navvalue;
};
export default Testfunction;
Content.js
import React from "react";
import Testfunction from "./Testfunction";
const Content = () => {
const navvalue = Testfunction();
return (
<p>Here´s the content. Insert value coming from Navbar here: {navvalue}</p>
);
};
export default Content;
To share some state in both <Navbar /> and <Content /> you can put state to their parent -> App. Also to <Navbar /> we pass setter function to update state which is in parent. So it can be like this:
import React from "react";
export default function App() {
const [navValue, setNavValue] = React.useState();
return (
<div className="App">
<Navbar setNavValue={setNavValue} />
<Content navValue={navValue} />
</div>
);
}
const Navbar = ({ setNavValue }) => {
const value = "Nav Value";
return <button onClick={() => setNavValue(value)}>{value}</button>;
};
const Content = ({ navValue }) => {
return (
<p>Here´s the content. Insert value coming from Navbar here: {navValue}</p>
);
};

Toggle one component from another using React hook

I have a two child components and I want a button in one of them to toggle (on/off) the html in another. I have watched tutorials on lifting state up, and communication between components but most of it has to do with moving data. I want to manipulate a component from another. I would like the achieve this using useState, and without useContext if possible. Thanks!
THE PARENT
import React from "react";
function App() {
return (
<div>
<AppProvider>
<ComponentOne/>
<Slideshow />
<ComponentTwo/ >
</AppProvider>
</div>
);
}
CHILD 1
export default function ComponentOne() {
return (
<div>
<button>The button that toggles</button>
</div>
);
}
CHILD 2
export default function ComponentTwo() {
return (
<div>
<div>The content that hides/shows</div>
</div>
);
}
You need to use state to toggle the values. Pass the state to the ComponentTwo as props and pass the state updater function as the callback function to the ComponentOne as a prop.
import React , { useState, useCallback } from 'react';
function ComponentOne({ onToggle}) {
return (
<div>
<button onClick={onToggle}>The button that toggles</button>
</div>
);
}
function ComponentTwo({show}) {
return (
<div>
{show && <div>The content that hides/shows</div>}
</div>
);
}
export default function App() {
const [show, setShow ] = useState(true);
const handleToggle = useCallback(() => setShow(prevShow => !prevShow),[])
return (
<div className="App">
<ComponentOne onToggle={handleToggle} />
<ComponentTwo show={show} />
</div>
);
}
Refer
useState
useCallback

React complains element type is invalid when trying to use context

I'm trying to use React Context to update navbar title dynamically from other child components. I created NavbarContext.js as follows. I have wrapped AdminLayout with NavContext.Provider and use useContext in Course.js to dynamically update navbar title inside useEffect. However, when I'm doing this, react throws the following error on the screen.
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
How can I use context properly so that I can update Header title from Course.js inside its useEffect?
NavbarContext.js
import React, {useState} from 'react'
export default () => {
const [name,setName] = useState("")
const NavContext = React.createContext({
name: "",
changeName: name => setName(name)
})
const NavProvider = NavContext.Provider
const NavConsumer = NavContext.Consumer
return NavContext
}
AdminLayout.js
<NavContext.Provider>
<div className={classes.wrapper}>
<Sidebar
routes={routes}
logoText={"Widubima"}
logo={logo}
image={image}
handleDrawerToggle={handleDrawerToggle}
open={mobileOpen}
color={color}
{...rest}
/>
<div className={classes.mainPanel} ref={mainPanel}>
<Navbar
routes={routes}
handleDrawerToggle={handleDrawerToggle}
{...rest}
/>
{/* On the /maps route we want the map to be on full screen - this is not possible if the content and conatiner classes are present because they have some paddings which would make the map smaller */}
{getRoute() ? (
<div className={classes.content}>
<div className={classes.container}>{switchRoutes}</div>
</div>
) : (
<div className={classes.map}>{switchRoutes}</div>
)}
</div>
</div>
</NavContext.Provider>
Navbar.js
import NavContext from "context/NavbarContext"
export default function Header(props) {
function makeBrand() {
var name;
props.routes.map(prop => {
if (window.location.href.indexOf(prop.layout + prop.path) !== -1) {
name = prop.name;
document.title = name;
}
return null;
});
return name;
}
return (
<AppBar className={classes.appBar + appBarClasses}>
<Toolbar className={classes.container}>
<div className={classes.flex}>
{/* Here we create navbar brand, based on route name */}
<NavContext.Consumer>
{({ name, setName }) => (
<Button
color="transparent"
href="#"
className={classes.title}
style={{ fontSize: "1.5em", marginLeft: "-2%" }}
>
{makeBrand() || name}
</Button>
)}
</NavContext.Consumer>
</Toolbar>
</AppBar>
);
}
Course.js
import React, { useState, useEffect, useContext } from "react";
import NavContext from "context/NavbarContext"
const AdminCourse = props => {
const context = useContext(NavContext);
useEffect(() => {
Axios.get('/courses/'+props.match.params.courseId).then(
res => {
context.changeName("hello")
}
).catch(err => {
console.log(err)
})
return () => {
setCourseId("");
};
});
return (
<GridContainer>
</GridContainer>
);
};
export default AdminCourse;
i think problem is there with your NavbarContext.js.
you are not exporting NavContext also.
you are defining provider, consumer but you are not using them either.
here's how you can solve your problem.
first create context and it's provider in a file as following.
NavContext.js
import React, { useState } from "react";
const NavContext = React.createContext();
const NavProvider = props => {
const [name, setName] = useState("");
let hookObject = {
name: name,
changeName: setName
};
return (
<NavContext.Provider value={hookObject}>
{props.children}
</NavContext.Provider>
);
};
export { NavProvider, NavContext };
in above code first i am creating context with empty value.
the i am creating NavProvider which actually contains value name as a state hook inside it.hookObject exposes state as per your naming conventions in code.
now i for testing purpose i defined two consumers.
one is where we update name in useEffect, that is ,
ConsumerThatUpdates.js
import React, { useContext, useEffect } from "react";
import { NavContext } from "./NavContext";
const ConsumerThatUpdates = () => {
const { changeName } = useContext(NavContext);
useEffect(() => {
changeName("NEW NAME");
}, [changeName]);
return <div>i update on my useeffect</div>;
};
export default ConsumerThatUpdates;
you can update useEffect as per your needs.
another is where we use the name,
ConsumerThatDisplays.js
import React, { useContext } from "react";
import { NavContext } from "./NavContext";
const ConsumerThatDisplays = () => {
const { name } = useContext(NavContext);
return <div>{name}</div>;
};
export default ConsumerThatDisplays;
and finally my App.js looks like this,
App.js
import React from "react";
import "./styles.css";
import { NavProvider } from "./NavContext";
import ConsumerThatDisplays from "./ConsumerThatDisplays";
import ConsumerThatUpdates from "./ConsumerThatUpdates";
export default function App() {
return (
<div className="App">
<NavProvider>
<ConsumerThatDisplays />
<ConsumerThatUpdates />
</NavProvider>
</div>
);
}
hope this helps!!
if you want to know more about how to use context effectively, i recooHow to use React Context effectively

Resources