This question already has answers here:
onClick doesn't render new react component.
(5 answers)
Closed 6 years ago.
I am new to reactjs and javascript. I am trying to create a very basic login and registration form. When a client enters email and password, and clicks 'register', the form should take him to next form- which is Contact Information form. But my page refreshes and brings me back to original screen instead of contact information screen. Here's the code for login and contact info-
import React from 'react';
import {render} from 'react-dom';
import { ContactInfo } from './ContactInfo.jsx'
var App = React.createClass ({
handleClick: function(){
<ContactInfo new="new"/>;
},
render: function() {
return (<div>
<h1>Login</h1>
<form>
Email: <input type="text" name="email" method="get" />
<br />
<br />
Password: <input type="password" name="pwd" />
<br />
<i>forgot password?</i>
<br /><br />
<button>Login</button>
<button onClick={this.handleClick}>Register</button>
</form>
</div>);
}
});
render(<App />, document.getElementById('app'));
and Contact Info:
import React from 'react';
var ContactInfo = React.createClass({
render: function(){
return(
<div>
<form>
Name: <input type="text"/>
<br />
<br />
Phone: <input type="text"/>
<br />
Address:
Street <input type = "text" />
<br />
City <input type = "text" />
<br />
State <input type = "text" /><p> </p>zip <input type = "text" />
<br />
Country <input type = "text" />
<br /><br />
<button>Continue</button>
</form>
</div>);
}
});
export default ContactInfo;
Your handleClick method isn't behaving properly. right now it contains some jsx which is doing absolutely nothing.
What you should probably do is
Have a parent component that handles which view you're on
Login form and ContactInfo are each their own separate components
Parent keeps track of which form it should be rendering on its state
onClick should be updating that state, which will then cause the parent to re-render and update which form it is rendering
Sooooo
Something like this
React.createClass ({
getInitialState: function () {
return {
currentForm: "login"
};
},
handleLoginFormClick: function () {
this.setState({currentForm: "contact"});
},
renderLoginForm: function () {
return (
<LoginForm onClick={this.handleLoginFormClick} />
);
},
renderContactForm: function () {
return (
<ContactForm />
);
},
render: function () {
switch (this.state.currentForm) {
case "login":
return this.renderLoginForm();
case "contact":
return this.renderContactForm();
}
}
});
Related
I am having problems using my if/else statement in React.js. Currently I am trying to have my program use an if/else statement to render to another program using the useNavigate hook with React Router. I only have one statement to see if when the answers are selected they render to another component.
Test Case
Description. After filling in the user survey, when the user hits submit the user will be sent to a specific page dedicated to their specific health needs.
Step 1): The user fills in the questions form
Expectation: the user fills in the form and it is shown which answers the user selected.
Actual: The user fills in the form and you can see the answers selected.
Step 2): The user then hits submit, and then with the users answers the page is then rendered to another page dedicated for that users health.
Expectation: The user is rendered/taken to another page to look over there exercise options.
Actual: Nothing happens, or I get some sort of unexpected token error.
Errors Exceptions
I keep getting the error:
[Intervention] Slow network is detected. See https://www.chromestatus.com/feature/5636954674692096 for more details. Fallback font will be used while loading: chrome-extension://liecbddmkiiihnedobmlmillhodjkdmb/fonts/CircularXXWeb-Book.woff2, which I have tried restarting my computer but that didn't help any, would this affect my code?
In my code I tried using an if/else and a switch statement, that would explain the zombie code.
Here is my code:
import React, { useState } from 'react';
import Introduction from './components/introduction';
import Questions from './components/beginning';
import Male from './components/questions';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
export default function App() {
return (
//Revisit <Route path="/questions" element= {<Male />} /> for Readability!!
<Router>
<Routes>
<Route path= "/" element={<Introduction />} />
<Route path="/beginning" element= {<Questions />} />
<Route path="/personalExercise" element={<personalExercise/>} />
<Route path="/questions" element= {<Male />} />
</Routes>
</Router>
);
}
import ReactDOM from "react-dom/client";
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />)
import React, { useState } from 'react';
import Form from 'react-bootstrap/Form';
import { useNavigate } from 'react-router-dom';
export default function Questions(props) {
const navigate = useNavigate()
const[formData, setFormData] = useState({
gender: "",
userAge: "",
goals:"",
});
function handleChange(event) {
const { name, value, type, checked } = event.target;
setFormData(prevFormData => {
return {
...prevFormData,
[name]: type === 'checkbox' ? checked : value
};
});
}
function handleSubmit(event) {
event.preventDefault()
navigate(getPath())
};
const getPath = () => {
if(formData.gender === "male" && formData.userAge === "Young" && formData.goals === "active"){
return navigate("/beginning")
}
// switch (formData) {
// case { gender: "male", userAge: "young", goals: "active" }: return navigate("../beginning");
// break;
// default:
// return navigate("/beginning")
// }
}
return (
<>
<header>Questions</header>
<Form onSubmit={handleSubmit}>
<fieldset>
<legend>What was your gender at birth</legend>
<input
type='radio'
id = 'male'
name = 'gender'
value = 'male'
checked={formData.gender === "male"}
onChange={handleChange}
/>
<label htmlFor="male"> Male </label>
<br />
<input
type='radio'
id='female'
name='gender'
value = 'female'
checked={formData.gender === "female"}
onChange={handleChange}
/>
<label htmlFor="female"> Female </label>
<br />
</fieldset>
<fieldset>
<legend>How old are you?</legend>
<input
type='radio'
id="young"
name="userAge"
value="young"
checked={formData.userAge === "young"}
onChange={handleChange}
/>
<label htmlFor="young"> 18-28 </label>
<br />
<input
type='radio'
id="middleAged"
name="userAge"
value="middleAged"
checked={formData.userAge === "middleAged"}
onChange={handleChange}
/>
<label htmlFor="middleAged"> 29-39 </label>
<br />
<input
type='radio'
id="older"
name="userAge"
value="older"
checked={formData.userAge === "older"}
onChange={handleChange}
/>
<label htmlFor="older"> 40-50 </label>
<br />
<input
type='radio'
id="senior"
name="userAge"
value="senior"
checked={formData.userAge === "senior"}
onChange={handleChange}
/>
<label htmlFor="senior"> 51+ </label>
<br />
</fieldset>
<br />
<fieldset>
<legend>What kind of fitness would you prefer?</legend>
<input
type="radio"
id="active"
name="goals"
value="active"
checked = {formData.goals === "active"}
onChange={handleChange}
/>
<label htmlFor='active'>To stay active!</label>
<br />
<input
type="radio"
id="weight"
name="goals"
value= "weight"
checked = {formData.goals === "weight"}
onChange={handleChange}
/>
<label htmlFor="weight"> To loose weight</label>
</fieldset>
<br />
<button>Submit</button>
</Form>
</>
)
}
import React from 'react';
import {NavLink} from 'react-router-dom'
import 'bootstrap/dist/css/bootstrap.min.css'
export default function beginning() {
return (
<>
<p>Before beginning, would you mind entering some info about yourself? This information
is used to help understand what kind of exercises suit you and lets the app know how
it can fit the 30 min sessions in your day!
</p>
<p>If you would like to skip the questionnaire and dive right into exercising, so you
can personally select what you want as your exercise, that is also an excellent
choice! </p>
<NavLink to="/questions">
<button>Take Questionnaire</button>
</NavLink>
<NavLink to="/exercise">
<button>Skip Questionnaire</button>
</NavLink>
</>
)
}
In your function getPath() you are returning the navigate function itself to navigate function. I think that is something which is triggering the error. Rather you can just call the getPath() function and remove the return keyword inside the if condition. If your condition is true it will navigate to the desired page or else nothing happens if the condition is not satisfied.
function handleSubmit(event) {
event.preventDefault()
getPath();
};
const getPath = () => {
if (formData.gender === "male" && formData.userAge === "Young" && formData.goals === "active") {
navigate("/beginning");
}
}
I am using react hook forms to create forms in my application:
import "./styles.css";
import { useForm } from "react-hook-form";
export default function App() {
const { register, setFocus, handleSubmit } = useForm({
defaultValues: { inputText: "", inputCheckbox: false }
});
const onSubmit = (data) => {
console.log(data);
};
return (
<div className="App">
<form onSubmit={handleSubmit(onSubmit)} className="form">
<br />
<label>inputCheckbox</label>
<input type="checkbox" {...register("inputCheckbox")} />
<br />
<br />
<label>inputCheckbox2</label>
<input type="checkbox" {...register("inputCheckbox")} />
<button
onClick={() => {
setFocus("inputCheckbox");
}}
>
setFocus inputCheckbox
</button>
<br />
<br />
<button type="submit">Submit</button>
</form>
</div>
);
}
I try to set focus when i click on the button, but it does not work, why and how to fix using the library API?
demo: https://codesandbox.io/s/icy-feather-eh1crv?file=/src/App.js:0-899
This question already has answers here:
How to pass data from a page to another page using react router
(5 answers)
Closed last month.
I am trying to understand how to pass data using React Router in my situation of using a form. I am currently creating a workout app and one of my pages is a survey for the user to fill out. Once the user has filled this survey out the data would be passed on to a file called personalExercise.js. In this personalExercise file, I would use conditional rendering to determine where the user is best suited per their preference.
Description of the attempted action:
Step 1). The user would answer the questions in the survey (from the file question.js) and the answers would be submitted to the console.
Step2).
Once the questions are submitted the data would be passed on to a file(file called personalExercise.js), where conditional rendering would be used to send the user to a page set to their exercise type.
Ex. In question.js file a user selects:
Male
18-28
Stay Active
The data then is transferred to the file personalExercise.js
Where through a conditional statement, the user would be sent to a specific page.
Ex. if (gender === male && userAge === young && goals === loose weight) { return (page specified to user) }
This is an idea and I am trying to use react Router to perform this task. Google has been my friend and enemy during my research.
import React from 'react';
import Introduction from './components/introduction';
import Questions from './components/beginning';
import Male from './components/questions';
import {BrowserRouter as Router, Route, Routes} from 'react-router-dom';
export default function App() {
return (
<Router>
<Routes>
<Route path= "/" element={<Introduction />} />
<Route path="/beginning" element= {<Questions />} />
<Route path="/questions" element= {<Male />} />
</Routes>
</Router>
);
}
PersonalExercise
import React from 'react';
import {NavLink} from 'react-router-dom'
import 'bootstrap/dist/css/bootstrap.min.css'
//purpose: To have the user see their specific exercises.
function personalExercise(formData) {
}
// function workout(){
// }
Questions
import React, {useState} from 'react';
import 'bootstrap/dist/css/bootstrap.min.css'
import Form from 'react-bootstrap/Form';
export default function Questions() {
const[formData, setFormData] = useState({
gender: "",
userAge: "",
goals:"",
});
function handleChange(event) {
const { name, value, type, checked } = event.target;
setFormData(prevFormData => {
return {
...prevFormData,
[name]: type === 'checkbox' ? checked : value
};
});
}
function handleSubmit(event) {
event.preventDefault()
console.log(formData)
};
return (
<>
<header>Questions</header>
<Form onSubmit={handleSubmit}>
<fieldset>
<legend>What was your gender at birth</legend>
<input
type='radio'
id = 'male'
name = 'gender'
value = 'male'
checked={formData.gender === "male"}
onChange={handleChange}
/>
<label htmlFor="male"> Male </label>
<br />
<input
type='radio'
id='female'
name='gender'
value = 'female'
checked={formData.gender === "female"}
onChange={handleChange}
/>
<label htmlFor="female"> Female </label>
<br />
</fieldset>
<fieldset>
<legend>How old are you?</legend>
<input
type='radio'
id="young"
name="userAge"
value="young"
checked={formData.userAge === "young"}
onChange={handleChange}
/>
<label htmlFor="young"> 18-28 </label>
<br />
<input
type='radio'
id="middleAged"
name="userAge"
value="middleAged"
checked={formData.userAge === "middleAged"}
onChange={handleChange}
/>
<label htmlFor="middleAged"> 29-39 </label>
<br />
<input
type='radio'
id="older"
name="userAge"
value="older"
checked={formData.userAge === "older"}
onChange={handleChange}
/>
<label htmlFor="older"> 40-50 </label>
<br />
<input
type='radio'
id="senior"
name="userAge"
value="senior"
checked={formData.userAge === "senior"}
onChange={handleChange}
/>
<label htmlFor="senior"> 51+ </label>
<br />
</fieldset>
<br />
<fieldset>
<legend>What kind of fitness would you prefer?</legend>
<input
type="radio"
id="active"
name="goals"
value="active"
checked = {formData.goals === "active"}
onChange={handleChange}
/>
<label htmlFor='active'>To stay active!</label>
<br />
<input
type="radio"
id="weight"
name="goals"
value= "weight"
checked = {formData.goals === "weight"}
onChange={handleChange}
/>
<label htmlFor="weight"> To loose weight</label>
</fieldset>
<br />
<button type='submit'>Submit</button>
</Form>
</>
)
}
You can try passing in a function like this in App.js
export default function App() {
const [data, setData] = useState({})
const getData = (data) =>{
setData(data)
}
return (
<Router>
<Routes>
<Route path= "/" element={<Introduction />} />
<Route path="/beginning" element={<Questions getData={getData}/>} />
<Route path="/personalExercise" element={<personalExercise data={data}/>} />
<Route path="/questions" element= {<Male />} />
</Routes>
</Router>
);
}
Then in your questions.js you can use the function like this
export default function Questions(props) {
function handleSubmit(event) {
event.preventDefault()
props.getData(formData)
};
}
And to access the data in personalExercise.js you can call props.data like this
export default function personalExercise(props){
return (
<>
{props.data}//whatever you want to conditionally render
</>
);
}
I am trying to build an E commerce web app where I handle the payments. First I need to take shipping information. I have successfully inserted data into mongo but I could not pass the data into another js right away from a single click.
Here is my create address page.
import React, { Component } from 'react'
import '../App.css'
import axios from 'axios'
export default class CreateAddress extends Component {
constructor(props) {
super(props);
this.state = {
address: "",
city: "",
phoneNo:"",
postalCode: "",
country: ""
}
}
handleInputChange = (e)=>{
const {name,value} = e.target;
this.setState({
...this.state,
[name]:value
})
}
onSubmit = (e)=>{
e.preventDefault();
const {address,city,phoneNo,postalCode,country} = this.state;
const data = {
address: address,
city: city,
phoneNo: phoneNo,
postalCode: postalCode,
country: country
}
console.log(data)
axios.post("http://localhost:5000/address/save",data).then((res)=>{
if(res.data.success){
this.setState(
{address: "",
city: "",
phoneNo:"",
postalCode: "",
country: ""}
)
alert("Shipping info added successfully");
}
})
}
render() {
return (
<div className="row wrapper">
<div className="col-10 col-lg-5">
<form className="shadow-lg" >
<h1 className="mb-4">Shipping Info</h1>
<div className="form-group">
<label htmlFor="address_field">Address</label>
<input
type="text"
id="address_field"
className="form-control"
name='address'
value={this.state.address}
onChange={this.handleInputChange}
required
/>
</div>
<div className="form-group">
<label htmlFor="city_field">City</label>
<input
type="text"
id="city_field"
className="form-control"
name='city'
value={this.state.city}
onChange={this.handleInputChange}
required
/>
</div>
<div className="form-group">
<label htmlFor="phone_field">Phone No</label>
<input
type="phone"
id="phone_field"
className="form-control"
name='phoneNo'
value={this.state.phoneNo}
onChange={this.handleInputChange}
required
/>
</div>
<div className="form-group">
<label htmlFor="postal_code_field">Postal Code</label>
<input
type="number"
id="postal_code_field"
className="form-control"
name='postalCode'
value={this.state.postalCode}
onChange={this.handleInputChange}
required
/>
</div>
<div className="form-group">
<label htmlFor="country_field">Country</label>
<input
type = "text"
id="country_field"
className="form-control"
name='country'
value={this.state.country}
onChange={this.handleInputChange}
required
/>
</div>
<button
id="shipping_btn"
type="submit"
className="btn btn-block py-3"
onClick={this.onSubmit}
>
SAVE
</button>
<button id="shipping_btn" type="submit" className = "btn btn-block py-3"><a href = "/confirm" style={{textDecoration:'none',color:'white'}}>PROCEED</a></button>
</form>
</div>
</div>
)
}
}
Once I clicked the PROCEED button the data should direct into /confirm page
You can use react-router to move between different routes in React. Also, in your code when you are sending a post request on onSubmit method, you are clearing the state information, which I think needs to be handled in the confirm page since you need the data in that page also.
Here's a codesandbox demonstrating how you can send the information to another page, using react-router. I've used the functional components, but the concepts works for the class based components also.
note: also you should use onSubmit handler of the form to submit values rather than using the onClick method of the button. Otherwise you force users to click the button to submit the form.
You can use history API to pass data as a URL and grab it into confirm page.
history.push(`/confirmPage?city=${city}&postalCode=${postalCode}`)
in confirmPage.js you will get that data as props
export default class ConfirmPage extends Component{
render(){
const {city, postalCode } = this.props.location.query;
return (
<div>{postalCode}</div>
)
}
I'm developing a dynamic component where the input can be used for several types: text, password, number, date, etc. The idea is to use this input, no matter the type and where to implement it, as long its adaptable. I thought using state was a nice idea, but I have no clue how to do this. Any thoughts?
import React, { Component } from 'react';
import './styles.css';
export default class InputField extends Component {
constructor(props) {
super(props);
this.state = {
name: '',
password: false,
type: ''
}
}
render () {
return (
<div>
<label className='f-size'>{this.state.name}</label>
<input
className='input'
name={this.state.name}
placeholder={this.state.name}
value={this.props.value}
type={this.state.type}
onChange={this.props.onChange}
/>
<span className="errorMessage">{this.props.error}</span>
<span className="errorMessage">{this.props.missField}</span>
</div>
)
}
}
Thank you!
I personally think you should control this via props, seeing as the value will only be meaningful to the Input's parent.
I used this
const InputField = ({
name,
placeholder,
value,
type,
onChange,
error,
missField
}) => (
<div>
<label className="f-size">{name}</label>
<input
className="input"
name={name}
placeholder={placeholder}
value={value}
type={type}
onChange={onChange}
/>
<span className="errorMessage">{error}</span>
<span className="errorMessage">{missField}</span>
</div>
);
Parent component:
class App extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
state = {
value: '',
password: '',
};
handleChange(event) {
this.setState({ [event.target.name]: event.target.value });
}
render() {
return (
<div className="App">
<InputField
value={this.state.value}
type="number"
name="value"
onChange={this.handleChange}
/>
<InputField
value={this.state.password}
type="password"
name="password"
onChange={this.handleChange}
/>
</div>
);
}
}
Code Sandbox: https://codesandbox.io/s/y4ljv75k9
Edited to used a stateless component. Not sure if you want state to handle error messages but from your example, this is a valid solution.
<InputField type="text" />
<InputField type="password" />
<input
className='input'
name={this.state.name}
placeholder={this.state.name}
value={this.props.value}
type={this.props.type}
onChange={this.props.onChange}
/>
I would use props to change the type and manage the component.
You could then control the component from a form definition
You should use props not state, so you can pass
<InputType type="text" />
<InputType type="password" />
<InputType type="number" />
and for the other params you can use props also.
You could use this.props.type but the standard jsx input component is already dynamic as you can see from my example below :
var root = document.getElementById('root');
class InputField extends React.Component {
render() {
return (
<div>
<input type={this.props.type} />
</div>
)
}
}
class App extends React.Component {
render() {
return (
<div>
<input type='date' />
<InputField type='password'/>
</div>
)
}
}
ReactDOM.render(<App />, root)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='root'></div>
Is there a reason why you would like to use a custom input component?