I have a radio input buttons in JSX like below.
import React, { Component, useState, useEffect, useRef } from 'react';
import { Link, Redirect } from 'react-router-dom';
import { useDispatch, connect } from 'react-redux';
import { updateReviewAction } from '../actions/dashboard';
const EditReviewComponent = (props) => {
const [role, setRole] = useState(null);
const [message, setMessage] = useState('');
const [isMessage, setIsMessage] = useState(false);
const [jobKnowledge, setJobKnowledge] = useState('');
const [productivity, setProductivity] = useState('');
const [workQuality, setWorkQuality] = useState('');
const [skills, setSkills] = useState('');
const dispatch = useDispatch();
const onUpdateReview = (event) => {
event.preventDefault();
let reviewID = props.viewReviews.response._id;
dispatch(updateReviewAction({ reviewID, jobKnowledge, productivity, workQuality, skills }));
setMessage('');
setIsMessage(true);
}
console.log(props.viewReviews);
const onRoleChange = event => {
setRole(event.target.value);
}
const onJobKnowledgeChange = event => {
setJobKnowledge(event.target.value);
}
const onProductivityChange = event => {
setProductivity(event.target.value);
}
const onWorkQualityChange = event => {
setWorkQuality(event.target.value);
}
const onSkillsChange = event => {
setSkills(event.target.value);
}
const resetMessage = () => {
setIsMessage(false);
}
return (
<div className='employees'>
<Link to={`${props.url}`}>Close</Link>
<h3>Edit New Employee</h3>
<p>{(message !== '' && isMessage) ? message : ''}</p>
<form onSubmit={onUpdateReview}>
<div>
<p>Job Knowledge</p>
<label htmlFor="excellent_knowledge">
<input
type="radio"
name="job_knowledge"
id="excellent_knowledge"
value="Excellent"
checked={
(props.viewReviews.hasOwnProperty('response') && props.viewReviews.response.jobKnowledge === 'Excellent')
? true
: false
}
onChange={onJobKnowledgeChange}
required
/>
Excellent
</label>
<label htmlFor="good_knowledge">
<input
type="radio"
name="job_knowledge"
id="good_knowledge"
value="Good"
checked={
(props.viewReviews.hasOwnProperty('response') && props.viewReviews.response.jobKnowledge === 'Good')
? true
: false
}
onChange={onJobKnowledgeChange}
required
/>
Good
</label>
<label htmlFor="fair_knowledge">
<input
type="radio"
name="job_knowledge"
id="fair_knowledge"
value="Fair"
checked={
(props.viewReviews.hasOwnProperty('response') && props.viewReviews.response.jobKnowledge === 'Fair')
? true
: false
}
onChange={onJobKnowledgeChange}
required
/>
Fair
</label>
<label htmlFor="poor_knowledge">
<input
type="radio"
name="job_knowledge"
id="poor_knowledge"
value="Poor"
checked={
(props.viewReviews.hasOwnProperty('response') && props.viewReviews.response.jobKnowledge === 'Poor')
? true
: false
}
onChange={onJobKnowledgeChange}
required
/>
Poor
</label>
</div>
<div>
<p>Productivity</p>
<label htmlFor="excellent_productivity">
<input
type="radio"
name="productivity"
id="excellent_productivity"
value="Excellent"
checked={
(props.viewReviews.hasOwnProperty('response') && props.viewReviews.response.productivity === 'Excellent')
? true
: false
}
onChange={onProductivityChange}
required
/>
Excellent
</label>
<label htmlFor="good_productivity">
<input
type="radio"
name="productivity"
id="good_productivity"
value="Good"
checked={
(props.viewReviews.hasOwnProperty('response') && props.viewReviews.response.productivity === 'Good')
? true
: false
}
onChange={onProductivityChange}
required
/>
Good
</label>
<label htmlFor="fair_productivity">
<input
type="radio"
name="productivity"
id="fair_productivity"
value="Fair"
checked={
(props.viewReviews.hasOwnProperty('response') && props.viewReviews.response.productivity === 'Fair')
? true
: false
}
onChange={onProductivityChange}
required
/>
Fair
</label>
<label htmlFor="poor_productivity">
<input
type="radio"
name="productivity"
id="poor_productivity"
value="Poor"
checked={
(props.viewReviews.hasOwnProperty('response') && props.viewReviews.response.productivity === 'Poor')
? true
: false
}
onChange={onProductivityChange}
required
/>
Poor
</label>
</div>
<div>
<p>Work Quality</p>
<label htmlFor="excellent_quality">
<input
type="radio"
name="quality"
id="excellent_quality"
value="Excellent"
checked={
(props.viewReviews.hasOwnProperty('response') && props.viewReviews.response.workQuality === 'Excellent')
? true
: false
}
onChange={onWorkQualityChange}
required
/>
Excellent
</label>
<label htmlFor="good_quality">
<input
type="radio"
name="quality"
id="good_quality"
value="Good"
checked={
(props.viewReviews.hasOwnProperty('response') && props.viewReviews.response.workQuality === 'Good')
? true
: false
}
onChange={onWorkQualityChange}
required
/>
Good
</label>
<label htmlFor="fair_quality">
<input
type="radio"
name="quality"
id="fair_quality"
value="Fair"
checked={
(props.viewReviews.hasOwnProperty('response') && props.viewReviews.response.workQuality === 'Fair')
? true
: false
}
onChange={onWorkQualityChange}
required
/>
Fair
</label>
<label htmlFor="poor_quality">
<input
type="radio"
name="quality"
id="poor_quality"
value="Poor"
checked={
(props.viewReviews.hasOwnProperty('response') && props.viewReviews.response.workQuality === 'Poor')
? true
: false
}
onChange={onWorkQualityChange}
required
/>
Poor
</label>
</div>
<div>
<p>Technical Skills</p>
<label htmlFor="excellent_skills">
<input
type="radio"
name="skills"
id="excellent_skills"
value="Excellent"
checked={
(
props.viewReviews.hasOwnProperty('response') &&
props.viewReviews.response.skills === 'Excellent'
)
}
onChange={onSkillsChange}
required
/>
Excellent
</label>
<label htmlFor="good_skills">
<input
type="radio"
name="skills"
id="good_skills"
value="Good"
checked={
(
props.viewReviews.hasOwnProperty('response') &&
props.viewReviews.response.skills === 'Good'
)
}
onChange={onSkillsChange}
required
/>
Good
</label>
<label htmlFor="fair_skills">
<input
type="radio"
name="skills"
id="fair_skills"
value="Fair"
checked={
(props.viewReviews.hasOwnProperty('response') && props.viewReviews.response.skills === 'Fair')
}
onChange={onSkillsChange}
required
/>
Fair
</label>
<label htmlFor="poor_skills">
<input
type="radio"
name="skills"
id="poor_skills"
value="Poor"
checked={
(props.viewReviews.hasOwnProperty('response') && props.viewReviews.response.skills === 'Poor')
}
onChange={onSkillsChange}
required
/>
Poor
</label>
</div>
<div>
<button>Update</button>
</div>
</form>
</div>
);
}
const mapStateToProps = state => (state);
export default connect(mapStateToProps)(EditReviewComponent);
as you can see I am checking them on a condition. With this condition they are properly checked. However, when I try to click on another radio button then it does not get checked anymore. The radio buttons are frozen.
What am I doing wrong and how can I fix it.
UPDATE
I updated the whole component. Please let me know what to do.
The checked attribute indicates the default value to be selected from the list of radio buttons. In your code you are trying to set checked from the props passed into the component, but this is not what you are updating when click one of the radio buttons.
When clicking a radio button, you are updating the state with these:
const [jobKnowledge, setJobKnowledge] = useState('');
const [productivity, setProductivity] = useState('');
const [workQuality, setWorkQuality] = useState('');
So, instead of determining the value of checked from props, try determining it using these state variables and I think it will work for you.
<input
type="radio"
name="job_knowledge"
id="excellent_knowledge"
value="Excellent"
checked={jobKnowledge === "Excellent"}
onChange={onJobKnowledgeChange}
required
/>
PS: Based on the way you were checking the value of this variable:
props.viewReviews.hasOwnProperty('response') && props.viewReviews.response.jobKnowledge === 'Excellent'
You might want to check out optional chaining
Related
I have a react component that contains a div with a conditional visibility. The component represents the page of a specific product on an ecommerce. The users can give their opinions once. The div with the conditional visibility contains a textarea to write this opinion. But it should only be visible if the user hasn't written a review yet. This decision must be taken before loading the component. How do I do that?
This is the component:
import Axios from "axios";
import React, { useEffect, useState } from "react";
import { Link, useParams } from "react-router-dom";
import NavbarHome from "./NavbarHome";
function Product() {
//Visivility of the form
let visibility = false;
useEffect(() => {
Axios.get("http://localhost:3001/review").then((response) => {
if (response.data.length === 0) {
visibility = true;
}
});
}, []);
const idprod = useParams();
//POST of the review
function handleSubmit(event) {
event.preventDefault();
let info = {
message: event.target.review.value,
rating: event.target.stars.value
};
if (!info.message || !info.rating) {
if (!info.message) {
alert("You haven't witten a review");
} else if (!info.rating) {
alert("You haven't give any stars");
}
} else {
Axios.post("http://localhost:3001/review", {
message: info.message,
rating: info.rating,
id_prod: idprod
}).then((response) => {
if (response.data.err) {
alert("You have already written a review for this product");
}
});
}
}
return (
<div>
<NavbarHome />
<div className="container-fluid" id="container-producto">
<div className="row">
<div className="col-sm-6 bloque-description-product">
<h2>Example</h2>
<p>Example</p>
<p>Example</p>
<p>Example</p>
</div>
</div>
<h4>Opinions</h4>
<div className="container-opinions">
{visibility ? (
<form onSubmit={handleSubmit}>
<p className="clasification">
<input id="radio1" type="radio" name="stars" value="5" />
<label htmlFor="radio1">★</label>
<input id="radio2" type="radio" name="stars" value="4" />
<label htmlFor="radio2">★</label>
<input id="radio3" type="radio" name="stars" value="3" />
<label htmlFor="radio3">★</label>
<input id="radio4" type="radio" name="stars" value="2" />
<label htmlFor="radio4">★</label>
<input id="radio5" type="radio" name="stars" value="1" />
<label htmlFor="radio5">★</label>
</p>
<textarea
name="review"
placeholder="Leave your review..."
></textarea>
<input type="submit"></input>
</form>
) : (
<div></div>
)}
</div>
</div>
</div>
);
}
export default Product;
The div with the conditional visibility is container-opinions.
I've already tried using onLoad on that container, but it is not working.
Any ideas?
You should change let variable with react state
import Axios from "axios";
import React, { useEffect, useState } from "react";
import { Link, useParams } from "react-router-dom";
import NavbarHome from "./NavbarHome";
function Product() {
const [visibility, setVisibility] = useState(false)
useEffect(() => {
Axios.get("http://localhost:3001/review").then((response) => {
if (response.data.length === 0) {
setVisibility(true);
}
});
}, []);
const idprod = useParams();
//POST of the review
function handleSubmit(event) {
event.preventDefault();
let info = {
message: event.target.review.value,
rating: event.target.stars.value
};
if (!info.message || !info.rating) {
if (!info.message) {
alert("You haven't witten a review");
} else if (!info.rating) {
alert("You haven't give any stars");
}
} else {
Axios.post("http://localhost:3001/review", {
message: info.message,
rating: info.rating,
id_prod: idprod
}).then((response) => {
if (response.data.err) {
alert("You have already written a review for this product");
}
});
}
}
return (
<div>
<NavbarHome />
<div className="container-fluid" id="container-producto">
<div className="row">
<div className="col-sm-6 bloque-description-product">
<h2>Example</h2>
<p>Example</p>
<p>Example</p>
<p>Example</p>
</div>
</div>
<h4>Opinions</h4>
<div className="container-opinions">
{visibility ? (
<form onSubmit={handleSubmit}>
<p className="clasification">
<input id="radio1" type="radio" name="stars" value="5" />
<label htmlFor="radio1">★</label>
<input id="radio2" type="radio" name="stars" value="4" />
<label htmlFor="radio2">★</label>
<input id="radio3" type="radio" name="stars" value="3" />
<label htmlFor="radio3">★</label>
<input id="radio4" type="radio" name="stars" value="2" />
<label htmlFor="radio4">★</label>
<input id="radio5" type="radio" name="stars" value="1" />
<label htmlFor="radio5">★</label>
</p>
<textarea
name="review"
placeholder="Leave your review..."
></textarea>
<input type="submit"></input>
</form>
) : (
<div></div>
)}
</div>
</div>
</div>
);
}
export default Product;
You'll want to use the useState react hook to keep track of the visibility in a way your app can react to:
import Axios from "axios";
import React, { useEffect, useState } from "react";
import { Link, useParams } from "react-router-dom";
import NavbarHome from "./NavbarHome";
function Product() {
//Visivility of the form
// THIS NEEDS TO BE useState
const [visibility, setVisibility] = useState(false)
useEffect(() => {
Axios.get("http://localhost:3001/review").then((response) => {
if (response.data.length === 0) {
// Use setVisibility to update the state
setVisibility(true);
}
});
}, []);
const idprod = useParams();
//POST of the review
function handleSubmit(event) {
event.preventDefault();
let info = {
message: event.target.review.value,
rating: event.target.stars.value
};
if (!info.message || !info.rating) {
if (!info.message) {
alert("You haven't witten a review");
} else if (!info.rating) {
alert("You haven't give any stars");
}
} else {
Axios.post("http://localhost:3001/review", {
message: info.message,
rating: info.rating,
id_prod: idprod
}).then((response) => {
if (response.data.err) {
alert("You have already written a review for this product");
}
});
}
}
return (
<div>
<NavbarHome />
<div className="container-fluid" id="container-producto">
<div className="row">
<div className="col-sm-6 bloque-description-product">
<h2>Example</h2>
<p>Example</p>
<p>Example</p>
<p>Example</p>
</div>
</div>
<h4>Opinions</h4>
<div className="container-opinions">
{visibility ? (
<form onSubmit={handleSubmit}>
<p className="clasification">
<input id="radio1" type="radio" name="stars" value="5" />
<label htmlFor="radio1">★</label>
<input id="radio2" type="radio" name="stars" value="4" />
<label htmlFor="radio2">★</label>
<input id="radio3" type="radio" name="stars" value="3" />
<label htmlFor="radio3">★</label>
<input id="radio4" type="radio" name="stars" value="2" />
<label htmlFor="radio4">★</label>
<input id="radio5" type="radio" name="stars" value="1" />
<label htmlFor="radio5">★</label>
</p>
<textarea
name="review"
placeholder="Leave your review..."
></textarea>
<input type="submit"></input>
</form>
) : (
<div></div>
)}
</div>
</div>
</div>
);
}
export default Product;
I have this React.js 'contact-us' code. I made a three radio buttons but they don't work. I want to make the select input disabled until I click on a specific radio button 'intrests in service'. When I click it: the select input will be enabled, else it stays disabled.
PS: I do not use function components, all in a class.
render() {
const { formErrors } = this.state;
return (
<div className='row'>
<div className='col-6'>
<h> Your Intrest : </h>
<div className='radio-btn'>
<label>
<input
type='radio'
name='service'
value={this.state.subject}
className={`for formInput ${formErrors.subject != 0 ? 'error' : null}`}
onChange={this.handleChange}
placeholder='Service'
noValidate
/> intrest in service. </label>
</div>
<div className='radio-btn'>
<label>
<input
type='radio'
name='team'
value={this.state.subject}
className={`for formInput ${formErrors.subject != 0 ? 'error' : null}`}
onChange={this.handleChange}
placeholder='Team'
noValidate
/> Join to our team. </label>
</div>
<div className='radio-btn'>
<label>
<input
type='radio'
name='another'
value={this.state.subject}
className={`for formInput ${formErrors.subject != 0 ? 'error' : null}`}
onChange={this.handleChange}
placeholder='Another'
noValidate
/> Another help.</label>
</div>
{formErrors.subject == 0 && (
<span className='errorMessage'>{formErrors.subject}</span>
)}
</div>
<div className='col-6'>
<h> Select Service: </h>
<select
type='select'
name='service'
value={this.state.service}
className={`form-control formInput ${formErrors.service.length > 0 ? 'error' : null}`}
onChange={this.handleChange}
placeholder='Service'
noValidate
disabled
>
<option>1</option>
<option>2</option>
<option>3</option>
</select>
{formErrors.service.length > 0 && (
<span className='errorMessage'>{formErrors.service}</span>
)}
</div>
...
handleChange method:
handleChange = (e) => {
e.preventDefault();
const { name, value } = e.target;
let formErrors = { ...this.state.formErrors };
case 'subject':
formErrors.subject = value.length < 1 ? 'Please enter a subject.' : '';
break;
case 'service':
formErrors.service = value.length < 1 ? 'Please enter a service.' : '';
break;
this.setState({ formErrors, [name]: value });
};
You need to update your radio buttons. The name of every radio button should be the same, this way you know that these belong to the same "group". The value is the value you want to store in your state.
You also need to add a checked prop. You set it true if the current input is the checked one and the one stored in your state.
If the state is correctly handled, you can check if the subject is the one required and disable the select field based on the state.
Check the snippet below and click on "Run code snippet", it should work as you described.
class App extends React.Component {
constructor() {
super();
this.state = {
service: "",
subject: ""
};
}
handleChange = (e) => {
this.setState({
[e.target.name]: e.target.value
});
};
render() {
return (
<div className="App">
<form>
<fieldset>
<label>
<input
type="radio"
name="subject"
checked={this.state.subject === "interest"}
onChange={this.handleChange}
value="interest"
/>{" "}
Interest in service
</label>
<label>
<input
type="radio"
name="subject"
checked={this.state.subject === "join team"}
onChange={this.handleChange}
value="join team"
/>{" "}
Join to our team
</label>
<label>
<input
type="radio"
name="subject"
checked={this.state.subject === "another"}
onChange={this.handleChange}
value="another"
/>
Another help
</label>
</fieldset>
<label>
Select Service:
<select
type="select"
name="service"
disabled={this.state.subject !== "interest"}
onChange={this.handleChange}
value={this.state.service}
>
<option>1</option>
<option>2</option>
<option>3</option>
</select>
</label>
</form>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById('root'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Well, maybe this is happening because of how I wrote my code. That happen because I am still learning React and all the stuff that I use in the code yesterday.
I am not yet even implementing a react tracker for the loading ui.
The purpose
I want to make a contact form for a course facilitator, but it is much more complex because I need image, checkbox for the program they choose, etc. At least for me that is complex than my blog.
Things that I have tried
I have tried it in development, it works like a charm.
The build also works seeing no problem.
The page after the build can still be visited.
The warning in Chrome
I get a violation in almost all of it. like in click handler, setTimeout, input handler.
The error that I get is three right after I click anything.
Two of the error start with error, but the last one is uncaught error. Maybe that does not matter?
Disclaimer
I may have used some Indonesian language in my code for name and stuff.
import React, { Component } from 'react';
import axios from 'axios';
import Header from "../components/Header"
import Footer from "../components/Footer"
export default class Daftar extends Component{
constructor(){
super();
this.state={
enable: false,
name:'',
email:'',
telepon:'',
program:'',
tempat_lahir:'',
tanggal_lahir:'',
selectedFile:'',
selectedFile1:'',
}
this.handleInputChange = this.handleInputChange.bind(this);
this.handleInputChange1 = this.handleInputChange1.bind(this);
}
handleChange = event =>{
this.setState({ [event.target.name]:event.target.value });
}
handleInputChange(event) {
this.setState({
selectedFile: event.target.files[0],
})
}
handleInputChange1(event) {
this.setState({
selectedFile1: event.target.files[0],
})
}
onChange(event){
let day_list = this.state.program;
let check = event.target.checked;
let checked_day = event.target.value;
if(check){
this.setState({
program: [...this.state.program, checked_day]
})
}else{
var index = day_list.indexOf(checked_day);
if (index > -1) {
day_list.splice(index, 1);
this.setState({
program: day_list
})
}
}
}
componentDidUpdate( prevState) {
if (
( prevState.email !== this.state.email )||
( prevState.name !== this.state.name )||
( prevState.telepon !== this.state.telepon) ||
prevState.program !== this.state.program
) {
if (this.state.email ||
this.state.name ||
this.state.subject ||
this.state.message
) {
this.setState({ enabled: true });
} else {
this.setState({ enabled: false });
}
}
}
handleSubmit = event =>{
event.preventDefault();
const KK = new FormData()
KK.append('kartu-keluarga', this.state.selectedFile)
console.warn(this.state.selectedFile);
const ijazah = new FormData()
ijazah.append('ijazah', this.state.selectedFile1)
console.warn(this.state.selectedFile1);
let url = `${process.env.GATSBY_DIRECTUS_API_URL}/gemaclc/items/pendaftar?access_token=${process.env.GATSBY_DIRECTUS_TOKEN}`;
let url2 = `${process.env.GATSBY_DIRECTUS_API_URL}/gemaclc/files?access_token=${process.env.GATSBY_DIRECTUS_TOKEN}`;
let id_ijazah;
let id_item;
let id_kk;
axios.post(url, {
status:"published",
nama: this.state.name,
email: this.state.email,
telepon: this.state.telepon,
program_yang_dipilih: this.state.program,
tanggal_lahir: this.state.tanggal_lahir,
tempat_lahir: this.state.tempat_lahir,
})
.then(res => {
console.log(res)
id_item = res.data.data.id;
return axios.post(url2, KK, )
})
.then(res => {
console.log(res)
console.log(res.data.data.id)
id_kk = res.data.data.id;
return axios.post(url2, ijazah, )
})
.then(res => {
console.log(res.data.data.id)
id_ijazah = res.data.data.id;
console.log(id_ijazah)
return axios( `${process.env.GATSBY_DIRECTUS_API_URL}/gemaclc/items/pendaftar/${id_item}?access_token=${process.env.GATSBY_DIRECTUS_TOKEN}`,
{
method:"patch",
data :{
kartu_keluarga: id_kk,
ijazah:id_ijazah
},
})
})
.then(res =>{
console.log(res)
})
.catch(error => {
console.log(error)
});
};
render(){
let form = "daftar-form"
let div = "daftar-div"
let div1 = "daftar-div1"
let label1 = "daftar-label1"
let label2 = "daftar-label2"
let label3 = "daftar-label3"
let checkbox = "daftar-checkbox"
let email = "daftar-email"
let nama = "daftar-nama"
let p1 = "daftar-p1"
let submitDisable = "daftar-submit-disable"
let submit = "daftar-submit"
let programDiv = "daftar-program-div"
return(
<div>
<Header/>
<div className={div}>
<div className={div1}>
<h1>Formulir Pendaftaran </h1>
<form onSubmit={this.handleSubmit} className={ form}>
<label className={label1}>
<span>
<p className={p1}> Nama : </p>
</span>
<input type="username" name="name" onChange={this.handleChange}
className={nama}
/>
</label>
<label className={label2}>
<span>
<p className={p1}> Email : </p>
</span>
<input type="email" name="email" onChange={this.handleChange}
className={email}
placeholder="name#location.com"/>
</label>
<label className={label3}>
<span>
<p className={p1}> telepon : </p>
</span>
<input type="tel" name="telepon" onChange={this.handleChange} className={nama}
/>
</label>
<label className={label3}>
<span>
<p className={p1}> Tempat Lahir : </p>
</span>
<input type="text" name="tempat_lahir" onChange={this.handleChange} className={nama}
/>
</label>
<label className={label3}>
<span>
<p className={p1}> Tanggal Lahir : </p>
</span>
<input type="date" name="tanggal_lahir" onChange={this.handleChange} className={nama}
/>
</label>
<div className={programDiv}>
<h3>Program yang Di pilih :</h3>
<label >
<input type="checkbox" onChange={this.onChange.bind(this)} name="program" className={checkbox}value="1"/>
<span>
<p className={p1}> paket A </p>
</span>
</label>
<label >
<input type="checkbox" onChange={this.onChange.bind(this)} name="program" className={checkbox}value="2"/>
<span>
<p className={p1}> paket B</p>
</span>
</label>
<label >
<input type="checkbox" onChange={this.onChange.bind(this)} name="program" className={checkbox}value={3}/>
<span>
<p className={p1}> paket C </p>
</span>
</label>
<label >
<input type="checkbox" onChange={this.onChange.bind(this)} name="program" className={checkbox}value={4}/>
<span>
<p className={p1}> English Regular 3 bulan </p>
</span>
</label>
<label >
<input type="checkbox" onChange={this.onChange.bind(this)} name="program" className={checkbox}value={5}/>
<span>
<p className={p1}> English Camp </p>
</span>
</label>
<label >
<input type="checkbox" onChange={this.onChange.bind(this)} name="program" className={checkbox}value={6}/>
<span>
<p className={p1}> English Private </p>
</span>
</label>
</div>
<div >
<div >
<br /><br />
<br />
<div >
<div >
<label className="text-white"> Kartu keluarga:</label>
<input type="file" name="upload_file"
onChange={this.handleInputChange} />
</div>
</div>
<div >
<div >
<label >ijazah :</label>
<input type="file" name="upload_file"
onChange={this.handleInputChange1} />
</div>
</div>
</div>
</div>
{this.state.enabled?<input type="submit" value="Kirim" className={submit}
/>:<input type="submit" value="Kirim" className={submitDisable} disabled/>}
</form>
<div><pre>{JSON.stringify(this.state.program) }</pre></div>;
</div>
</div>
<Footer/>
</div>
)
}
}
i found it, i just update from
componentDidUpdate( prevState) {
if (
( prevState.email !== this.state.email )||
( prevState.name !== this.state.name )||
( prevState.telepon !== this.state.telepon) ||
prevState.program !== this.state.program
) {
if (this.state.email ||
this.state.name ||
this.state.subject ||
this.state.message
) {
this.setState({ enabled: true });
} else {
this.setState({ enabled: false });
}
}
}
to this
componentDidUpdate(prevProps, prevState) {
if (
( prevState.email !== this.state.email )||
( prevState.name !== this.state.name )||
( prevState.telepon !== this.state.telepon) ||
prevState.program_yang_dipilih !== this.state.program_yang_dipilih
) {
if (this.state.email ||
this.state.name ||
this.state.telepon ||
this.state.program_yang_dipilih
) {
this.setState({ enabled: true });
} else {
this.setState({ enabled: false });
}
}
}
So I'm trying to enable a button, after two fields have been selected, but for some reason, I have to click on the second field twice to trigger it to enabled. Can anyone see what I'm doing wrong?
So to confirm, when I click on a price and when I click on donateTo field, it is setting state correctly, however it doesn't enable the bottom at the bottom until I have clicked one of the fields a third or fourth time.
const DonateBox = ({ goToPayment }) => {
const [price, setPrice] = useState('');
const [donateTo, setDonateTo] = useState('');
const [isProgressDisabled, setDisabled] = useState(true);
const handleSetDonateTo = (e) => {
setDonateTo(e.target.value);
disabledCheck();
};
const handlePriceClick = (e) => {
setPrice(e.target.value);
disabledCheck();
};
const handleGoToPayment = () => {
goToPayment('paymentbox');
};
const disabledCheck = () => {
if (price && donateTo) {
setDisabled(false);
}
console.log(isProgressDisabled);
};
return (
<>
<div className={styles.donateBox}>
<p className={styles.heading}>
Give through the most effective platform for good.
</p>
<p className={styles.subheading}>
100% goes to the causes listed in the article here. You are one click
away!
</p>
<div className={styles.itemList}>
<label className={styles.labelWrapper}>
<input
type="radio"
className={styles.customRadio}
value="cause"
onClick={handleSetDonateTo}
checked={donateTo === 'cause'}
/>
<span>Donate to Cause</span>
</label>
<label className={styles.labelWrapper}>
<input
type="radio"
className={styles.customRadio}
value="charity"
onClick={handleSetDonateTo}
checked={donateTo === 'charity'}
/>
<span>Donate to Charity</span>
</label>
<label className={styles.labelWrapper}>
<input
type="radio"
className={styles.customRadio}
value="goods"
onClick={handleSetDonateTo}
checked={donateTo === 'goods'}
/>
<span>Donate to Goods</span>
</label>
</div>
<div className={styles.priceList}>
<label
className={`${styles.priceLabel} ${
price === '25' ? `${styles.selected}` : ''
}`}
>
<input
type="radio"
name="25"
className={styles.priceInput}
onClick={handlePriceClick}
value="25"
/>
$25
</label>
<label
className={`${styles.priceLabel} ${
price === '50' ? `${styles.selected}` : ''
}`}
>
<input
type="radio"
name="50"
className={styles.priceInput}
onClick={handlePriceClick}
value="50"
/>
$50
</label>
<label
className={`${styles.priceLabel} ${
price === '75' ? `${styles.selected}` : ''
}`}
>
<input
type="radio"
name="75"
className={styles.priceInput}
onClick={handlePriceClick}
value="75"
/>
$75
</label>
</div>
</div>
<button
className={styles.largeButton}
onClick={handleGoToPayment}
disabled={isProgressDisabled}
>
Add Card Details
</button>
</>
);
};
export default DonateBox;
In addition to #adesurirey's suggestion, this is the perfect scenario for useEffect.
When the variable(s) inside of the dependency array are changed, the code in useEffect is invoked.
Meaning, you can automatically invoke the disabledCheck if price or donateTo are changed. This way you don't have to remember to call disabledCheck within the handlers.
Edit another excellent thing about useEffect in a scenario like this is that you know for sure disabledCheck is invoked only after state is changed. Since mutating state is async, it is possible that disabledCheck was running before state was actually updated.
Think of useEffect like the callback function within setState (on class based components)..
// Class based comparison...
// You know for sure `disabledCheck` is only called *after*
// state has been updated
setState({
some: 'newState'
}, () => disabledCheck());
Demo:
const { useState, useEffect, Fragment } = React;
const { render } = ReactDOM;
const DonateBox = ({ goToPayment }) => {
const [price, setPrice] = useState('');
const [donateTo, setDonateTo] = useState('');
const [isProgressDisabled, setDisabled] = useState(true);
const handleSetDonateTo = (e) => {
setDonateTo(e.target.value);
// disabledCheck();
};
const handlePriceClick = (e) => {
setPrice(e.target.value);
// disabledCheck();
};
const handleGoToPayment = () => {
goToPayment('paymentbox');
};
const disabledCheck = () => {
if (price !== '' && donateTo !== '') {
setDisabled(false);
}
console.log(isProgressDisabled);
};
useEffect(() => {
disabledCheck();
}, [price, donateTo]);
return (
<Fragment>
<div>
<p>
Give through the most effective platform for good.
</p>
<p>
100% goes to the causes listed in the article here. You are one click
away!
</p>
<div>
<label>
<input
type="radio"
value="cause"
onClick={handleSetDonateTo}
checked={donateTo === 'cause'}
/>
<span>Donate to Cause</span>
</label>
<label>
<input
type="radio"
value="charity"
onClick={handleSetDonateTo}
checked={donateTo === 'charity'}
/>
<span>Donate to Charity</span>
</label>
<label>
<input
type="radio"
value="goods"
onClick={handleSetDonateTo}
checked={donateTo === 'goods'}
/>
<span>Donate to Goods</span>
</label>
</div>
<div>
<label>
<input
type="radio"
name="25"
onClick={handlePriceClick}
value="25"
/>
$25
</label>
<label>
<input
type="radio"
name="50"
onClick={handlePriceClick}
value="50"
/>
$50
</label>
<label>
<input
type="radio"
name="75"
onClick={handlePriceClick}
value="75"
/>
$75
</label>
</div>
</div>
<button
onClick={handleGoToPayment}
disabled={isProgressDisabled}
>
Add Card Details
</button>
</Fragment>
);
};
const App = () => <DonateBox />
render(<App />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.1/umd/react-dom.production.min.js"></script>
You should use onChange events on your inputs instead of onClick
<input
type="radio"
name="75"
className={styles.priceInput}
onChange={handlePriceClick}
value="75"
/>
I am not able to click or select on any of my radio buttons. Can someone help me out how to work with radio buttons in react?
I tried removing e.preventDefault() but that didn't help either.
Here's what my code looks like:
File 1:
this.state = {
fields: {
gender: ''
}
}
fieldChange(field, value) {
this.setState(update(this.state, { fields: { [field]: { $set: value } } }));
}
<Form
fields={this.state.fields}
onChange={this.fieldChange.bind(this)}
onValid={() => handleSubmit(this.state.fields)}
onInvalid={() => console.log('Error!')}
/>
File 2:
render() {
const { fields, onChange, onValid, onInvalid, $field, $validation } = this.props;
return (
{/* Gender */}
<div id={styles.genderField} className={`form-group ${styles.formGroup} ${styles.projName}`}>
<label className="col-sm-2 control-label">Gender:</label>
<div className="col-sm-10">
<label className="radio-inline">
<input type="radio" name="gender" id="male"
checked={fields.gender === "Male"}
value={fields.gender} {...$field( "gender", e => onChange("gender", e.target.value)) } />
Male
</label>
<label className="radio-inline">
<input type="radio" name="gender" id="female"
checked={fields.gender === "Female"}
value={fields.gender} {...$field( "gender", e => onChange("gender", e.target.value)) } />
Female
</label>
</div>
</div>
<div className={`modal-footer ${styles.modalFooter}`}>
<button
className={`btn btn-primary text-white ${styles.saveBtn}`}
onClick={e => {
e.preventDefault();
this.props.$submit(onValid, onInvalid);
}}
>
Save
</button>
</div>
)
}
That's not how the docs handle onChange events. https://reactjs.org/docs/handling-events.html
You need to provide the full code to be able to help with that particular component.
Check out this working example: https://stackblitz.com/edit/react-radiobtns
class App extends Component {
constructor(props) {
super(props);
this.state = {selectedOption: 'option1'};
// This binding is necessary to make `this` work in the callback
this.handleOptionChange = this.handleOptionChange.bind(this);
}
handleOptionChange(changeEvent) {
this.setState({
selectedOption: changeEvent.target.value
});
}
render() {
return (
<form>
<label>
<input
onChange={this.handleOptionChange}
type="radio" value="option1"
checked={this.state.selectedOption === 'option1'}
name="radio1"/>
Option 1
</label>
<label>
<input
onChange={this.handleOptionChange}
checked={this.state.selectedOption === 'option2'}
type="radio"
value="option2"
name="radio1"/>
Option 2
</label>
<label>
<input
onChange={this.handleOptionChange}
checked={this.state.selectedOption === 'option3'}
type="radio"
value="option3"
name="radio1"/>
Option 3
</label>
</form>
);
}
}