Button Navigation with React Router - javascript

Header: I am trying to navigate to a new page from my Material UI button using the onClick method. I am confused about what to write in my handleClickSignIn function.
Code snippet from my Header.tsx file:
const HatsPage = () => (
<div>
<h1>
HATS PAGEHH
</h1>
</div>
)
function handleClickSignIn() {
<Route component= {HatsPage}></Route>
}
const Header = () => (
<div className = 'header'>‚
<h1 className = 'title'>
Instaride
</h1>
<div className="header-right">
<Button onClick= {handleClickSignIn}> Sign In</Button>
<Button> Contact</Button>
</div>
</div>
);
This doesn't work and I get errors like:
expected assignment or function but got expression instead

The problem you're having it that you're generating a Route component every time the Sign In button is clicked.
Instead, you should use a Link component like so:
const Header = () => (
<div className = 'header'>‚
<h1 className = 'title'>
Instaride</h1>
<div className="header-right">
<Link to={"/login"}> Sign In</Link>
<Button> Contact</Button>
</div>
</div>
This will create a link component that, when clicked, will direct to the /login URL. To then render components at that URL you'll also need to define a Route. You've already done this with but need to define the path like so:
<Route path={"/login"} component={HatsPage} />
And then note that this Route, your Header component and any Link's need to be nested within an instance of a BrowserRouter.

Related

How to call a component inside a custom component in React?

I want to change the body dynamically, how can i do this?
import React from 'react'
// import { Link } from 'react-router-dom'
export default function ProjectTemplate(props) {
const Css= {
"--background":`${props.isValue ? props.mode : 'red'}`
}
return (
<>
<div className="bodyCon projectCon">
<div className="bodyComponent">
<div className="aboutHeading projectHeading" style={Css}>
<h1>{props.name}</h1>
<div className="container">
<div className="projects">
</div>
</div>
</div>
</div>
</div>
</>
)
}
this is a custom component
import React from 'react'
import ProjectTemplate from '../Projects/ProjectTemplate/ProjectTemplate'
export default function Blog(props) {
return (
<>
<ProjectTemplate name='Blog' mode={props.mode} isValue={props.isValue} >
hhhh
</ProjectTemplate>
</>
)
}
this is the another component where i want to add the body of previous component dynamically, then the hhh is not display in browser
output in browser:
<div className="bodyCon projectCon">
<div className="bodyComponent">
<div className="aboutHeading projectHeading" style={Css}>
<h1>{props.name}</h1>
<div className="container">
<div className="projects">
hhh
</div>
</div>
</div>
</div>
</div>
but hhh is not visible in browser, how can i do for this output
You should read this docs, all you need here is children props
The word hhh will not be displayed because you are calling the custom component in the project template with no props name which you want to display. In your code if you render the component the Blog name will displayed only.
use this in the project template and pass the props to the childrenanme
<div className="projects">
{props.childrenanme}
</div>
To Answer your Question: Yes we can use component inside nested component in react.
In JSX expressions that contain both an opening tag and a closing tag,
the content between those tags is passed as a special prop React Documentation.
And to use these special props you have to use {props.children}.
In your example, you have passed the content b/w opening and closing tag of a custom component but forgot to use it.
In projectTemplate component use the children that you have passed while invoking the component, like this:
<div className="projects">
{props.childrenanme}
</div>

React Button Click should change the display value of div

I got a Navbar which has a button do change the display value of a login form. The Login form and the Login form is a diffrent file, the navbar is a diffrent file and the homepage where it should be display is a diffrent file. Those are the minimal variants of each so that you got some got to understand my problem in detail:
Homepage:
const HomePage = () => {
return (
<div>
<Navbar />
<Login />
<div id="content">
</div>
</div>
);
}
Navbar:
const Navbar= () => {
const showLogin = () => {
document.getElementById('Login').style.display='block';
}
return (
<div id="Navbar">
<NavLink activeClassName="active" to='/'><img src={logo}/></NavLink>
<ul>
...
</ul>
<ul>
<button onClick={showLogin}>Anmelden</button>
</ul>
</div>
);
}
Login-Form:
const Login = () => {
return (
<div id="Login">
<form>
<label>Anmelden</label>
<label for="username">Nutzername</label>
<input name="username" type="text"></input>
<label for="pw">Passwort</label>
<input name="pw" type="password"></input>
<button type="submit">Login</button>
</form>
</div>
);
}
Is there a way to achieve this, or would my easiest option be to include the Login source code into the Navbar source code?
You do not need to move your Login component inside Navbar. Keep it as it is.
You can use useState and Props to switch css classes to show/hide your Login component. I have created very simple solution for you in this CodeSandbox.
Steps:
Create two CSS classes hidden and block
In your Login component add a boolean prop which switches class hidden to block if true.
Create a prop for onClick in the Login component.
Create a useState inside your Homepage which holds a boolean value. That boolean value pass it to the Login page prop and then use onClick prop from Navbar to switch that boolean state
Yes, depending on your CSS system this is easily achievable just by using that.
The React solution is using refs.
The easy way is to create a ref in the parent component and then pass it down as a prop to both components:
In Homepage (i.e. parent), create a ref like so loginRef = useRef(); then pass it down as a prop to the 2 children.
In Login-Form.js you assign that prop on the div with id Login like so <div id='Login' ref={props.loginRef}>
Then in Navbar.js you can use that prop to change its display value like so const showLogin = () => {props.loginRef.current.style.display='block';}
NB: This is a fast and easy way, not best practice but it gets the work done. The best-practice here is to use forwardRef and - super advanced - useImperativeHandle. Take your time and go through the documentation when you're ready.
Login page will show "it is not active" first because active is set to false.but once you click on submit button it will show "it is active"
HomePage
const HomePage = () => {
const[active,setActive]=useState(false);
return (
<div>
<Navbar activesetter={setActive} />
<Login activestatus={active} />
<div id="content">
</div>
</div>
);
}
Login
const Login = (props) => {
return(
<div>
<div>
{props.activestatus ? "it is active" : "it is not active" }
</div>
</div>
);
}
Navbar
const Navbar = (props) => {
const handleSubmit=(e)=> {
e.preventDefault();
props.activesetter(true);
}
return(
<div>
<form onSubmit={handleSubmit}>
<button type="submit">Login</button>
</form>
</div>
);
}

Changing State of a Component by Input from children

I've got three forms - sign in, forgot password and sign up. Initial render is for a sign in component which has buttons for forget password or sign up. On click the buttons render their each respective component.
Where I am right now is that I have state assigned to each child component I want rendered and buttons changing the state in the parent component . I want to move these buttons to the child components so that I can change the state from there
Below is the sign in page and two of the three components I've mentioned.
export default function SigninPage() {
const [comp, setView] = useState('signin')
function toggleSignin(comp){
setView('signin')
}
function toggleReset(comp){
setView('reset')
}
function toggleSignup(comp){
setView('signup')
}
return (
<LoginStyles>
{comp ==='signin' &&(
<div>
<SignIn />
</div>
)
}
{comp ==='reset' &&(
<div><RequestReset/></div>
)
}
{comp ==='signup' &&(
<div><SignUp/></div>
)
}
<button onClick={toggleSignin}>Sign In</button>
<button onClick={toggleReset}>Forgot Password</button>
<button onClick={toggleSignup}>Sign Up</button>
</div>
);
}
export default function SignIn() {
return (
<Form>
<h2>Sign Into Your Account</h2>
<button type="submit">Sign In</button>
{/* onClick sets state to 'signup'*/}
<a>Create a New Account</a>
<a>Forgot Password</a>
</Form>
);
}
export default function RequestReset() {
return (
<Form >
{/* onClick sets state to 'signin'*/}
<a href='/signin'>**Go back**</a>
<h2>Request a Password Reset</h2>
<fieldset>
<label htmlFor='email'>
Email
</label>
<button type='submit'>Request Reset</button>
</fieldset>
</Form>
)
}
First off, I believe you should implement this behavior with routing, that approach you are using is definitely messy and hard to follow.
That said, I think the follow will do the trick:
<LoginStyles>
{items.map(({ id, component, isVisible }) => (
const Component = component;
<div key={id} hidden={!isVisible}>
<Component onClickComponent={() => handleClick(id)}
</div>
))}
</LoginStyles>
Of course you need to call onClickComponent later on in the childs, but you will have scope and keep the id.

React pass ref throw functional components in different levels

I would like to scroll to menu element in a page.
I have the menu component which is not a parent of components to which I would like to scroll.
I have found this post that describe a similar problem
Passing ref to a child We want the ref to be attached to a dom element, not to a react component. So when passing it to a child
component we can't name the prop ref.
const myRef = useRef(null)
return <ChildComp refProp={myRef}></ChildComp> } ```
Then attach the ref prop to a dom element. ```jsx const ChildComp =
(props) => {
return <div ref={props.refProp} /> } ```
Here's my app structure
Menu component:
const MenuApp = () => {
return (
<div>
<div className="desktop-menu">
<div className="menu-item a-propos">
<p className='button'>Me découvrir</p>
</div>
<div className="menu-item competences">
<p className='button'>Compétences </p>
</div>
<div className="menu-item experiences">
<p className='button'>Experiences</p>
</div>
<div className="menu-item formation">
<p className='button'>Formation </p>
</div>
</div>
</div>
)
}
The parent is app component
<div className="App">
<div className="hero">
<HeaderApp />
<ApprochApp />
</div>
<Apropos />
<Competences />
<Experiences />
<Formation />
<Recom />
<Contact />
<Footer />
</div >
I would like that mu menus scrolls to the react components in the main App component
So how can I passe the reference from the menu component to the app and use it in components to scroll ?
I do not understand your problem completely though. However, one thing I can see from your question is that you're not forwarding the ref properly.
What you need in this case is forwardRef.
Basically, what you need to do is to create the childComponent as something like this:
const childComponent = React.forwardRef(({...otherProps}, ref) => {
return (<><div ref={ref}>Component content </div></>)
})
Where you need to use the component all you need to do is this:
const parentComponent = () => {
const reveiwsRef = React.useRef("");
return (
<div>
<childComponent ref={reviewsRef} />
</div>
);
}
You can find more info about this on the react documentation: Forwarding-Refs
I have hope this helps though

How to add odd/even class to wrapping divs

I'm trying to build a page where I want to wrap each component inside a div which either has an "odd" or "even" class so that I can set different background-colors. I'm pretty new to gatsby and react so I wonder how to do that?
I followed the instructions how to set up an gatsby-project here and this is what I got so far:
index.js:
const IndexPage = () => (
<div className="page-container">
<component-1 />
<component-2/>
<component-3/>
<component-4/>
<component-5/>
</div>
)
export default IndexPage
what I want is something like this
const IndexPage = () => (
<div className="page-container">
<div className="odd">
<component-1 />
</div>
<div className="even">
<component-2 />
</div>
<div className="odd">
<component-3 />
</div>
<div className="even">
<component-4 />
</div>
</div>
)
export default IndexPage
I just called my components silly names for display reasons...
How can I achive this?

Categories

Resources