React Button Click should change the display value of div - javascript

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>
);
}

Related

How do i pass data values to modals using react hooks?

I am working on using modals to accept form inputs on a react project
here is the plan component
plan/index.js
import React, { useState } from "react";
import Pay from '../Pay';
const Plan = () => {
const [payModal, setPayModal] = useState(false);
const [planMode, setPlanMode] = useState(true);
return (
<main class="main">
{payModal && <Pay setOpenPayModal={setPayModal} />}
<div class="plan">
<div>
<a class="plans" onClick={() => {setPayModal(true);}}>plan A</a>
<div class="plan">
<span class="plan">{!planMode ? "$19.99" : "$9.99"}</span>
<span class="plan">{!planMode ? "month" : "year"}</span>
</div>
</div>
<div>
<a class="plans" onClick={() => {setPayModal(true);}}>plan B</a>
<div class="plan">
<span class="plan">{!planMode ? "$29.99" : "$19.99"}</span>
<span class="plan">{!planMode ? "month" : "year"}</span>
</div>
</div>
</div>
</main>
);
};
export default Plan;
as you can see on the line {payModal && <Pay setOpenPayModal={setPayModal} />} where i call the pay modal component from the plan component and it opens up the modal
here is the pay component which is the modal component
pay/index.js
import React, { useState } from "react";
function Pay({ setOpenPayModal }) {
const [billingDetails, setBillingDetails] = useState({
price: "",
: "",
});
return (
<div class="modal">
<div class="modal">
<div class="close">
<button
onClick={() => {
setOpenPayModal(false);
}}
>
</button>
</div>
<div class="modal">
<form class="form" onSubmit={handleSubmit}>
<fieldset class="form">
<Field
label="Price"
id="price"
type="text"
value={billingDetails.price}
onChange={(e) => {
setBillingDetails({ ...billingDetails, price: e.target.value });
}}
/>
<Field
label="Frequency"
id="frequency"
type="text"
value={billingDetails.frequency}
onChange={(e) => {
setBillingDetails({ ...billingDetails, frequency: e.target.value });
}}
/>
</fieldset>
<button class="pay" onClick={handleSubmitPay}>
Pay
</button>
</form>
</div>
</div>
</div>
);
}
export default Pay;
The issue is I want to be able to pass the values price and frequency from the plan component to the pay modal component
for example for plan A is price="$19.99" and frequency="year", so based on the button clicked on the plan component page, those values get passed to the pay modal component in a dynamic way
how do I achieve this using react hooks?
You can use contexts to pass, but in this case I don't think it's the best option. What I really recommend is passing the state variable through the props.
{payModal && <Pay setOpenPayModal={setPayModal} price={price} frequency={frequency} />}
I usually use the Context (useContext) when I need values and various components, for example:
I need to save the user id that is logged in to various components, and instead of getting it from the server every time I need it, I keep it saved in my context that I created, so I can make the call only once.
Documentation-> https://pt-br.reactjs.org/docs/context.html

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

Button Navigation with React Router

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.

React input focus event to display other component

I was read some tutorial about this. They told me should using ref to do that.
But It's very general.
Here is my problem:
Basically in Header component include NavBar, SearchBar and ResultSearch component.
const Header = () => {
return (
<header className="ss_header">
<Navbar />
<SearchBar />
<ResultSearch />
</header>
);
};
And In SearchBar component. Whenever I focused on input text. It emit an event and display ResultSearch component by any way (changing style, or ...).
class SearchBar extends Component{
render() {
return (
<div className="search_bar">
<section className="search">
<div className="sub_media container">
<form method="GET" action="" id="search_form">
<Icon icon="search" />
<span className="autocomplete">
<input
className="search_input"
autoCorrect="off"
autoComplete="off"
name="query"
type="text"
placeholder="Search for a movie, tv show, person..." />
</span>
</form>
</div>
</section>
</div>
);
}
}
Style in ResultSearch component. I was set display: none.
.results_search { display: none; }
I think ResultSearch will receive an event from SearchBar and set back display: block for ResultSearch component. Is possible?
How can I handle that?
My Code here: https://codesandbox.io/s/3xv8xnx3z5
only you should convert Header component like following:
class Header extends Component {
state = {
focus: false
};
handleInputFocus = () => {
this.setState({ focus: true });
};
handleInputBlur = () => {
this.setState({ focus: false });
};
render() {
return (
<header className="ss_header">
<SearchBar
onFocus={this.handleInputFocus}
onBlur={this.handleInputBlur}
/>
{this.state.focus ? <ResultSearch /> : null}
</header>
);
}
}
and also in SearchBar component add following attributes to your input:
onFocus={this.props.onFocus}
onBlur={this.props.onBlur}
also, you should remove your CSS about result box.
And, you can see the updated code on the following sandbox:
https://codesandbox.io/s/mmj46xkpo9
Still not sure what you're trying to achieve.
This is the way you can handle visibility of result of the search. Let me know if this isn't what you're looking for.
https://codesandbox.io/s/7jvz31xr66

Categories

Resources