Changing state on route change in React - reactjs

I want to show a select tag when a checkbox is checked.
In "/register" route (which is the default route), checkbox should be unchecked by default and in "/register/tradeUser", checkbox should be checked by default.
If I use defaultChecked="true", the state of checked will not change to true.
So I want to know, how can I call setChecked(true) inside the conditional rendering?
const Register = (match) => {
const [checked, setChecked] = useState(false);
const toggleChecked = () => {
if (checked) {
setChecked(false);
} else {
setChecked(true);
}
};
return (
<form>
<input type="text" name="first-name" placeholder="First Name" />
<input type="text" name="last-name" placeholder="Last Name" />
<input type="email" name="email" placeholder="Email Address" />
<input type="password" name="password" placeholder="Password" />
<input type="password" name="confirm" placeholder="Confirm Password" />
{match.location.pathname === "/register/tradeUser" ? (
<div>
<label>
<input
type="checkbox"
name="profession"
checked={checked}
onChange={() => toggleChecked()}
/>
I am an Architect/Interior designer
</label>
<select
name="info"
placeholder="Select Option to add Architect Info"
className={`${checked ? "" : "hidden"}`}
>
<option value="certi-number">Certificate Number</option>
<option value="certificate">Registration Certificate</option>
</select>
</div>
) : (
<div>
<label>
<input
type="checkbox"
name="profession"
checked={checked}
onChange={() => toggleChecked()}
/>
I am an Architect/Interior designer
</label>
<select
name="info"
placeholder="Select Option to add Architect Info"
className={`${checked ? "" : "hidden"}`}
>
<option value="certi-number">Certificate Number</option>
<option value="certificate">Registration Certificate</option>
</select>
</div>
)}
<button>Register</button>
</form>
<label>
Existing User?
<Link to="/login" className="link">
{" Login "}
</Link>
</label>
</div>
);
};

you can easily run function in jsx like this
export default function App() {
return (
<div className="App">
{console.log(1)}
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
</div>
);
}
however you shouldn't set state in jsx because it will loop infinitely
in this case you can use useEffect
useEffect(()=>{
if(match.location.pathname=== "/register/tradeUser"){
setChecked(true)
}else{
setChecked(false)
}
},[match.location.pathname])

Related

Reactjs - how can i take input from one component(inputbox) and use it in other component

I am building a MOVIE Search API app and I am taking input from one serah input box from the user with help of following code
import React, { Component } from "react";
import styles from "../styles/Example.module.css";
import Appletv from "../appletv.json";
import Link from 'next/link';
export default class example extends Component {
constructor(props) {
super(props);
this.state = {
movies: "",
filteredShows: Appletv.shows, // Starting with all shows
};
}
handMoviesChange = (event) => {
this.setState({
movies: event.target.value,
});
};
handleSubmit = (event) => {
event.preventDefault();
const newFilteredShows = Appletv.shows.filter((show) => {
return (
this.state.movies === "" ||
show.Title.toLowerCase().includes(this.state.movies.toLowerCase())
);
});
this.setState({ filteredShows: newFilteredShows });
};
render() {
console.table(Appletv.shows);
return (
<div className={styles.container}>
<h3 className={styles.Title}>SearchTest</h3>
<form onSubmit={this.handleSubmit}>
<div className={styles.row}>
<input
className={styles.input}
id="search"
type="input"
required
placeholder="Please enter title"
value={this.state.movies}
onChange={this.handMoviesChange}
/>
</div>
<Link href="/searchtest">
<button className={styles.button} type="submit">
Search
</button>
</Link>
</form>
<div className={styles.results} >
{this.state.filteredShows.map((filteredShows, index) => {
return (
<div>
{/* <h1 className={styles.title}>{filteredShows.Title}</h1>
<img
className={styles.image}
src={filteredShows.Thumbnail}
alt="Thumbnail"
/>
<h5 className={styles.genre}>
{filteredShows.Genre} & {filteredShows["Release date"]}
</h5>
<p className={styles.desc}>{filteredShows.Description}</p> */}
</div>
);
})}
</div>
</div>
);
}
}
Output of this code is following
and I want to get those results in the second component and second component code is following
import React, { Component, useState } from "react";
import styles from "../styles/Home.module.css";
import Appletv from "../appletv.json";
import Pagination from "./components/Pagination";
/* import Netflixlogo from "../logos/netflix.png";
*//* import Appletvlogo from "../logos/appletv.png";
import dstvlogo from "../logos/dstv.png";
import Amzonlogo from "../logos/amzon.png";
import Showmaxlogo from "../logos/showmax.png"; */
export default class searchtest extends Component {
constructor(props) {
super(props);
this.state = {
movies: "",
filteredShows: Appletv.shows, // Starting with all shows
};
}
handMoviesChange = (event) => {
this.setState({
movies: event.target.value,
});
};
handleSubmit = (event) => {
event.preventDefault();
/* const filteredShows = array.slice(0, 6);
*/
const newFilteredShows = Appletv.shows.filter((show) => {
return (
this.state.movies === "" ||
show.Title.toLowerCase().includes(this.state.movies.toLowerCase())
);
});
this.setState({ filteredShows: newFilteredShows });
};
render() {
console.table(Appletv.shows);
return (
<div className={styles.container}>
{/* <h3 className={styles.Title}>SearchTest</h3>
*/}
{/* <h4 className={styles.searche}>Search Results</h4>
*/}{" "}
<input
className={styles.searchin}
id="search"
type="input"
required
placeholder="Please enter title"
value={this.state.movies}
onChange={this.handMoviesChange}
/>{" "}
<button className={styles.searchbtn} type="submit">
Search
</button>{" "}
<div className={styles.row}>
<form onSubmit={this.handleSubmit}>
<div className={styles.row}>
<h4>Filtering Options</h4>
<label className={styles.label}>Movies</label>
<input
id="name"
className={styles.checkbox}
type="checkbox"
required
/>
</div>
<div className={styles.row}>
<label className={styles.label}>TV Show</label>
<input id="name" className={styles.checkbox} type="checkbox" />
</div>
<hr className={styles.hr} />
{/* <div className={styles.row}>
<input
className={styles.input}
id="search"
type="input"
required
placeholder="Please enter title"
value={this.state.movies}
onChange={this.handMoviesChange}
/>
</div>
<div className={styles.row}>
<input
className={styles.input}
type="text"
list="genre"
placeholder="Please Choose Genre"
/>
<datalist id="genre">
<option className={styles.option}>scifi</option>
<option>Documentry</option>
</datalist>
</div>
<div className={styles.row}>
<input
className={styles.input}
id="name"
type="input"
placeholder="Season Input"
/>
</div> */}
<div className={styles.row}>
<label className={styles.label}>Netflix</label>
<input className={styles.checkbox} id="name" type="checkbox" />
</div>
<div className={styles.row}>
<label className={styles.label}>Amazon Prime</label>
<input className={styles.checkbox} id="name" type="checkbox" />
</div>
<div className={styles.row}>
<label className={styles.label}>Apple TV+</label>
<input
className={styles.checkbox}
id="name"
type="checkbox"
required
/>
</div>
<div className={styles.row}>
<label className={styles.label}>Showmax</label>
<input
className={styles.checkbox}
id="name"
type="checkbox"
required
/>
</div>
<div className={styles.row}>
<label className={styles.label}>DSTV</label>
<input
className={styles.checkbox}
id="name"
type="checkbox"
required
/>
</div>
<hr className={styles.hr} />
<label for="cars" className={styles.label}>
Select Year
</label>
<div className={styles.row}>
<select
name="cars"
id="cars"
data-toggle="dropdown"
className={styles.dropdown}
>
{/* <option value=""></option>
*/} <option value="2015">2015</option>
<option value="2016">2016</option>
<option value="2017">2017</option>
<option value="2018">2018</option>
<option value="2019">2019</option>
<option value="2020">2020</option>
<option value="2021">2021</option>
</select>
</div>
<label for="cars" className={styles.label}>
Select Genre
</label>
<div className={styles.row}>
<select
name="cars"
id="cars"
data-toggle="dropdown"
className={styles.dropdown}
>
{/* <option value=""></option>
*/} <option value="SCIFI">SCIFI</option>
<option value="comedy">COMEDY</option>
<option value="ADVENTURE">ADVENTURE</option>
<option value="DOCUMENTRY">DOCUMENTRY</option>
</select>
</div>
<label for="cars" className={styles.label}>
Select Age Restriction
</label>
<div className={styles.row}>
<select
name="cars"
id="cars"
data-toggle="dropdown"
className={styles.dropdown}
>
{/* <option value=""></option>
*/} <option value="SCIFI">18+</option>
<option value="comedy">Adult</option>
<option value="ADVENTURE">Kids</option>
<option value="DOCUMENTRY">Cartoons</option>
</select>
</div>
<button className={styles.button} type="submit">
Apply Filters
</button>
</form>
</div>
<div className={styles.results}>
{/* here we are going to do conditional rendering like if netflix checkbox clicked then show or else not */}
{/* <img className={styles.condimg}
src={""}
alt="condren"
/> */}
<h4 className={styles.h2}>Search Results for {this.state.title}</h4>
{this.state.filteredShows.slice(0,4).map((filteredShows, index) => {
return (
<div>
<h1 className={styles.title}>{filteredShows.Title}</h1>
<img
className={styles.image}
src={filteredShows.Thumbnail}
alt="Thumbnail"
/>
<h5 className={styles.genre}>
{filteredShows.Genre} & {filteredShows["Release date"]}
</h5>
<p className={styles.desc}>{filteredShows.Description}</p>
</div>
);
})}
</div>
<Pagination/>
</div>
);
}
}
and output of the second component is like this
and can anyone help me for getting data from the first component to another second component I know we can do it with help of props and I am not getting how can I do that can anyone help me with this.
you can pass state through React router
<Link
to={{
pathname: '/pathname',
state: { results: 'this is results' }
}}
/>
In the component you can access the variable like this:
componentDidMount: function() {
var results= this.props.location.state.results
},
hope it help :D
You can add a prop (function) onUpdate to your search component, then call this function when you submit your search. On the parent-component, you can then add logic to pass it to your other component. For example, you add it to a state, which is then passed to your second component.
handMoviesChange = (event) => {
this.setState({
movies: event.target.value,
});
this.props.onUpdate(event.target.value);
};
Then in your parent component:
<example onUpdate={(movies) => setState({ movies })} />
<searchtest movies={this.state.movies} />
Hope it helps.

Radio buttons with react-hook-form

I created a form with react-hook-form. It logs "fullName" and "city" correctly in the console, but not the radio buttons. With the radio buttons you get as result "null".
My code is as follows.
import React from 'react'
import './App.css';
import {useForm} from "react-hook-form";
function App() {
const {register, handleSubmit} = useForm();
function onSubmitButton(data) {
console.log(data)
}
return (
<>
<h1>Order weather</h1>
<form onSubmit={handleSubmit(onSubmitButton)}>
<input
{...register("fullName")}
type="text"
name="fullName"
placeholder="Name and surname"
id="name"
/>
<input
{...register("city")}
type="text"
name="city"
placeholder="City"
id="city"
/>
<p>I would like to:</p>
<label htmlFor="field-rain">
<input
{...register("rain")}
type="radio"
name="weather"
value="rain"
id="field-rain"
/>
Rain
</label>
<label htmlFor="field-wind">
<input
{...register("wind")}
type="radio"
name="weather"
value="wind"
id="field-wind"
/>
Lots of wind
</label>
<label htmlFor="field-sun">
<input
{...register("sun")}
type="radio"
name="weather"
value="sun"
id="field-sun"
/>
Sunny
</label>
<button type="submit">
Send
</button>
</form>
</>
);
}
export default App;
When I turn off name= "weather" and I check the buttons it does put it in the console, but it is not supposed to allow me to check all the buttons at the same time. Anyone have an idea how I can make sure I can get what is checked into the console?
Since rain, wind, sun should be assign to the same value we need to pass same params to register function as below
function App() {
const {register, handleSubmit} = useForm();
function onSubmitButton(data) {
console.log(data)
}
return (
<>
<h1>Order weather</h1>
<form onSubmit={handleSubmit(onSubmitButton)}>
<input
{...register("fullName")}
type="text"
placeholder="Name and surname"
id="name"
/>
<input
{...register("city")}
type="text"
placeholder="City"
id="city"
/>
<p>I would like to:</p>
<label htmlFor="field-rain">
<input
{...register("weather")}
type="radio"
value="rain"
id="field-rain"
/>
Rain
</label>
<label htmlFor="field-wind">
<input
{...register("weather")}
type="radio"
value="wind"
id="field-wind"
/>
Lots of wind
</label>
<label htmlFor="field-sun">
<input
{...register("weather")}
type="radio"
value="sun"
id="field-sun"
/>
Sunny
</label>
<button type="submit">
Send
</button>
</form>
</>
);
}
export default App;
I hope this will fix the issue.

How to Reset the dropdown values on form submission, Other Input values are getting Cleared in React Hooks

I have a form and when I click on submit button, the data gets submitted to server.
Now, After the data got submitted to server, I Need to clear the Form data to empty.
Every fields gets clear other than Dropdown value.What was Issue Here??
const Form = () => {
const [data, setdata] = useState({
"UserName" : "",
"PhoneNumber" : "",
"email" : "",
"dropDown" :"",
})
const [update, setUpdate] = useState([])
const handleChange =(e)=>{
setdata({...data,[e.target.name]:e.target.value});
}
const handleSubmit=(e)=>{
e.preventDefault();
// setUpdate({...data,update});
// console.log(data);
axios.post('url',data).then((res)=>{
// console.log("user added successfully");
handleClear();
})
}
So, here I wrote the function to clear the form and I called that function after the submitting the form
const handleClear=()=>{
let clear={
"UserName" : "",
"PhoneNumber" : "",
"email" : "",
"dropDown" :"",
}
setdata(clear);
}
return (
<React.Fragment>
<h1>LordShiva</h1>
<div className="container mt-3">
<div className="row">
<div className="col-md-6">
<div className="card">
<div className="card-header bg-success text-white">
<h4>Form</h4>
<form>
<div className="form-group">
<input type="text" className="form-control" placeholder='UserName' name="UserName" value={data.UserName} onChange={handleChange} />
</div>
<div className="form-group">
<input name="phone" className="form-control" placeholder='PhoneNumber' name="PhoneNumber" value={data.PhoneNumber} onChange={handleChange} />
</div>
{/* <div className="form-group">
<DatePicker selected={startDate} placeholder='Select Date' />
</div> */}
<div className="form-group">
<input name="email" className="form-control" placeholder='Email' value={data.email} onChange={handleChange} />
</div>
<div className="form-group">
<select name="dropDown" onChange={handleChange} className="form-control" >
<option value=""></option>
<option value="Reactjs">ReactJS</option>
<option value="JS">JavaScript</option>
<option value="csCSSs">CSS</option>
<option value="HTML">HTML</option>
</select>
</div>
<div className="form-row">
<button className="btn btn-cyan" type="button" onClick={handleSubmit}>Submit</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</React.Fragment >
)
}
Pass the dropdown state value to the value prop of the select element.
<select
name="dropDown"
value={data.dropdown} // <-- set value to make a controlled input
onChange={handleChange}
className="form-control"
>
<option value=""></option>
<option value="Reactjs">ReactJS</option>
<option value="JS">JavaScript</option>
<option value="csCSSs">CSS</option>
<option value="HTML">HTML</option>
</select>

Formik radio box not selectable

I have a working React component with Formik with initialValues and everything else works perfectly except for the radio box below.
The radio box is not selectable, what could be the bug?
<Field
name="accountPurpose"
render={({ field }) => (
<>
<div className="radio-item">
<input
{...field}
id="all"
value="all"
checked={field.value === "all"}
name="type"
type="radio"
/>
<label htmlFor="all"> All</label>
</div>
<div className="radio-item">
<input
{...field}
id="distribution"
value="distribution"
name="type"
checked={field.value === "distribution"}
type="radio"
/>
<label htmlFor="distribution">
Distribution
</label>
</div>
<div className="radio-item">
<input
{...field}
id="redemption"
value="redemption"
name="type"
checked={field.value === "redemption"}
type="radio"
/>
<label htmlFor="redemption">
{" "}
Redemption
</label>
</div>
</>
)}
/>
Remove checked={field.value ===...} from all inputs and use defaultChecked for just one.
like below
<input
id="all"
value="all"
name="type"
type="radio"
defaultChecked
{...field}
/>

React conditional divs with hooks

I am creating a signup form that will render differently depending on whether the person signing up chooses Post a project or Work on a project from the very first div in the form.
How can I render each div that follows in the form-group conditionally based on what is selected in the first div? I am using hooks and I have found that most examples are for the extends Component approach.
My form:
const signUpForm = () => (
<form onSubmit={clickSubmit}>
<div className="form-group">
<select onChange={handleChange("role")} class="form-control">
<option selected>I want to...</option>
<option>Post a project</option>
<option>Work on a project</option>
</select>
</div>
<div className="form-group">
<input
onChange={handleChange("name")}
type="text"
placeholder="Name"
className="form-control"
value={name}
/>
</div>
<div className="form-group">
<input
onChange={handleChange("email")}
type="email"
placeholder="Email"
className="form-control"
value={email}
/>
</div>
<div className="form-group">
<input
onChange={handleChange("password")}
type="password"
placeholder="Password"
className="form-control"
value={password}
/>
</div>
<div className="form-group">
<input
onChange={handleChange("studying")}
type="text"
placeholder="I'm studying..."
className="form-control"
value={studying}
/>
</div>
<div>
<div>{createInputs()}</div>
<button
className="btn btn-outline-primary btn-sm mb-3"
onClick={addSkill}
type="text"
>
Add more skills
</button>
</div>
<button onClick={clickSubmit} className="btn btn-primary" type="submit">
Sign Up
</button>
</form>
);
State:
const Signup = () => {
const [values, setValues] = useState({
name: "",
email: "",
password: "",
studying: "",
skills: [""],
error: "",
success: "",
role: ""
});
const { name, email, password, studying, skills, success, error, role } = values;
handleChange():
const handleChange = name => event => {
setValues({ ...values, error: false, [name]: event.target.value });
};
You should first divide the signUp in two parts and then call second function based on value of "role" from state.
The idea is to return the divs from second function based on state of first input.
const signUpForm = () => (
<form onSubmit={clickSubmit}>
<div className="form-group">
<select onChange={handleChange("role")} class="form-control">
<option selected>I want to...</option>
<option>Post a project</option>
<option>Work on a project</option>
</select>
</div>
{this.renderInput()}
<button onClick={clickSubmit} className="btn btn-primary" type="submit">
Sign Up
</button>
</form>
);
renderInput() {
if (values.role === "post") {
return (
<div className="form-group">
<input onChange={handleChange("name")} type="text" placeholder="Name" className="form-control" value={name} />
</div>
<div className="form-group">
<input onChange={handleChange("email")} type="email" placeholder="Email" className="form-control" value={email} />
</div>
<div className="form-group">
<input onChange={handleChange("password")} type="password" placeholder="Password" className="form-control" value={password} />
</div>
<div className="form-group">
<input onChange={handleChange("studying")} type="text" placeholder="I'm studying..." className="form-control" value={studying} />
</div>
<div>
<div>{createInputs()}</div>
<button className="btn btn-outline-primary btn-sm mb-3" onClick={addSkill} type="text">
Add more skills
</button>
</div>
);
}
}
You want to test the role state value is truthy/falsey and render the rest of your form on that value.
const SignUpForm = () => (
<form onSubmit={clickSubmit}>
<div className="form-group">
<select
defaultValue='unselected' // set default value here
onChange={handleChange("role")}
className="form-control" // fix className here, class alone isn't correct in react
>
<option value='unselected'>I want to...</option>
<option value='post'>Post a project</option>
<option value='work'>Work on a project</option>
</select>
</div>
{!!role && (
<Fragment>
<div className="form-group">
<input
onChange={handleChange("name")}
type="text"
placeholder="Name"
className="form-control"
value={name}
/>
</div>
<div className="form-group">
<input
onChange={handleChange("email")}
type="email"
placeholder="Email"
className="form-control"
value={email}
/>
</div>
<div className="form-group">
<input
onChange={handleChange("password")}
type="password"
placeholder="Password"
className="form-control"
value={password}
/>
</div>
<div className="form-group">
<input
onChange={handleChange("studying")}
type="text"
placeholder="I'm studying..."
className="form-control"
value={studying}
/>
</div>
<div>
<div>{createInputs()}</div>
<button
className="btn btn-outline-primary btn-sm mb-3"
onClick={addSkill}
type="text"
>
Add more skills
</button>
</div>
</Fragment>
)}
<button onClick={clickSubmit} className="btn btn-primary" type="submit">
Sign Up
</button>
</form>
);

Resources