how to get the checked value of a radio button using react - reactjs

I have below radio button Component
import React from 'react';
import PropTypes from 'prop-types';
export default class RadioButton extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
}
handleChange = (event) => {
this.props.handleChange(event);
}
render() {
return (
<div>
<input type="radio" name="measureValue" value={this.props.value} onChange={this.handleChange} checked={true}/>
<label>{this.props.value}</label>
</div>
);
}
}
Im using this component as
handleRadioSelect = (event) =>{
this.setState({
selectedRadioValue : event.target.value
})
}
<RadioButton value="Fact" handleChange = { this.handleRadioSelect }/>
Now,I got the error as handleChnage is not a function.

to get value of checked, use the event.target.checked instead of event.target.value, so that:
handleRadioSelect = (event) =>{
this.setState({
radioChecked : event.target.checked
})
}
And your error appear because you need to use the arrow function to this.handleCheck (so you can pass in the event props) so that:
onChange={e => this.handleCheck(e)}
In this case, you do not need to bind it anymore and just use normal function for the handleCheck so that:
handleChange(event) {
this.props.handleChange(event);
}
This is how I normally approach it, hope that helps!

handleChange = (event) => {
let target = event.target;
let name = target.name;
let value = target.type === 'checkbox' ? target.checked : target.value;
this.setState({
[name] : value
})
}
Hope this helps

Related

React-why event target value is undefined

I am working on a shared component, which is an input textarea
The component is:
class TextBox extends React.Component {
constructor(props) {
...
const value = this.props.value;
this.state = {
value: value
}
}
handleChange(e, v) {
console.log("event: ", e);
this.setState({value: e.target.value}, () => {this.props.handleChange(e, v)});
}
render() {
const {
name
} = this.props;
const {
value
} = this.state;
return (
<div>
<h2>{name}</h2>
<textarea
value={value}
onChange={this.handleChange}
/>
</div>
);
}
}
Using this component:
const [comment, setComment] = useState('');
const handleChange = useCallback((e, v) => {
setComment(v);
}, [comment]);
....
<TextBox
name="comment"
value={comment}
handleChange={handleChange}
/>
The console log shows event.target.value is undefined
I have no idea why, can someone help? Thanks in advance
===update===
Thank you all! The problem is fixed
This should be target and value from the first parameter:
handleChange = (e) => {
console.log("event: ", e);
console.log("value: ", e.target.value);
this.setState({value: e.target.value}, () => {this.props.handleChange(e, v)});
}
Inside the above function:
e - Window.Event
e.target - <textarea> element in JS.
e.target.name will be the name attribute.
e.target.value will be the value attribute.
Also I'll suggest you to use Arrow Functions, else you might need to bind the function to this on the constructor, which is not being followed now-a-days.
You have to bind the handleChange function in constructor like below:
this.handleChange=this.handleChange.bind(this);
You can also use arrow function like this way:
handleChange=(e)=>{//...content here}
Also, there is no such parameter as v. The only parameter should be e.

handleChange in the parent component and child?

What I am trying to do is:
on the parent component I have onChange=this.handleChange that it works fine for textInputs and it allows me to go to the next steps of my form but it doesn't setState of dropDowns whatever I do my dropdowns are empty and if I setState dropdowns on the child I am unable to trigger the handleChange on the parent thing that I need
class CompanyInfo extends React.Component {
constructor(props) {
super(props);
this.state = {
value: this.props.company,};
this.handleChange = this.props.onChange.bind(this);
}
render() {
return(
<SelectInput value={this.state.value}
onChange={this.handleChange}
floatingLabelText={messages.company[lang]}
floatingLabelFixed={true}
>
{this.props.company.map((element) => {
return <MenuItem value={element.Value} primaryText={element.Value} />})}
</SelectInput>
parent:
handleChange = (event) => {
console.log("test");
const { stepIndex } = this.state;
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
var type = null;
switch(stepIndex) {
case 0: type='UPDATE_CINFO'; break;
case 1: type='UPDATE_PINFO'; break;
default: break;
}
this.props.dispatch(updateCurrentForm( type, { [name]: value } ));
this.setState( this.state , () => this.validateFields() )
}
Just use the prop of handleChange directly in the child component. And you also should control the state only at one place and use the state values as props in child components.
render() {
const {handleChange, company} = this.props
return(
<SelectInput value={company}
onChange={handleChange}
floatingLabelText={messages.company[lang]}
floatingLabelFixed={true}
>
...
}

event.target.value returns undefined with semantic UI when I console log it

I am trying to set the state for when someone clicks on the checkbox. I can get this to work with a normal checkbox type but can't with semantic ui as my values are returned as undefined. 'Input name undefined. Input value undefined.' I was wondering if someone could help me out here.
Thanks!
import React, { Component } from 'react';
import { Input, Dropdown, TextArea, Form, Button, Header, Checkbox } from 'semantic-ui-react'
class PageTwo extends Component {
constructor(props){
super(props)
this.state = {
programAgreement: false;
}
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
console.log(`Input name ${name}. Input value ${value}.`);
this.setState({
[name]: value
});
}
<Checkbox
placeholder="I Agree"
name="programAgreement"
type="checkbox"
checked={this.state.programAgreement}
onChange={this.handleInputChange} />
/>
you can have two params every time onChange triggered.
onChange(event: SyntheticEvent, data: object)
event
React's original SyntheticEvent.
data
All props and proposed checked/indeterminate state.
try this below code:
handleInputChange(event,data) {
this.setState({
[data.name]: !data.checked
});
}
live demo
try to use second parameter
handleInputChange(e, data) {
console.log(data);
const value = data.type === "checkbox" ? data.checked : data.value;
const name = data.name;
console.log(value);
console.log(name);
this.setState({
[name]: value
});
};

Using functional setState in forms

I have been learning react and on setState i get about functional setState, i wanted to implement this on the forms to see how it works ( please don't give me counter example,i am seeing if it can be implemented in forms for usage only ).
I am trying to do this because i saw similar approach in a github but he had included all the things inside the single object, so he is doing it easily. But my question is can i do the same but without including my form properties like username and password inside object. I am talking about this repo => Form Container. What do you people recommend? How may i can do ? Thanks !
My form code is like this:
index.js
import React,{ Component } from 'react';
import ReactDOM from 'react-dom';
class Form extends Component{
constructor(props){
super(props);
this.state = {
name: "",
age: "",
};
}
handleInput = (e) => {
let name = e.target.name;
let value = e.target.value;
this.setState({ [name]: value });
}
//The block where i am trying to implement the function setState
handleInput = (e) => {
let name = e.target.name;
let value = e.target.value;
this.setState( state => ({
name:{state.name,[name]: value}
}));
}
render(){
return(
<div>
<label> Name:
<input type="text" name="name" value={this.state.name} onChange={this.handleInput} />
</label>
<br />
<label> Age:
<input type="text" name="age" value={this.state.age} onChange={this.handleInput} />
</label>
</div>
);
}
}
ReactDOM.render(<Form />, document.getElementById('root'))
handleInput = ({ target }) => {
const { name, value } = target;
this.setState({ [name]: [value] });
}
//Can even boil down to one line of code
handleInput = ({ target }) => this.setState({ [target.name]: [target.value] })
You may try the code above. It's pretty concise and not sure how to elaborate on it. We can discuss about my approach in comment
UPDATES:
let value = e.target.value;
this.setState( prevState => ({
newUser : { ...prevState.newUser, name: value }
}), () => console.log(this.state.newUser))
The above code was copied from the link you commented which in our case, should be implemented as below:
handleInput = ({ target }) => {
const { name, value } = target;
this.setState(prevState => ({ ...prevState, [name]: value }));
}

Class not applied to the input element reactjs

currently, want to style an input element when the input element is not empty and the user has entered text. Below is the code snippet. Class is applied when !input_active but when condition is set to (!input_active && !inputEmpty) class does not apply to the input element.
constructor(props) {
super(props);
this.input_text_ref = React.createRef();
this.state = {
input_active: true,
};
}
focus = () => {
console.log("focus");
this.setState({
input_active: true
});
};
blur = () => {
console.log("blur");
this.setState({
input_active: false
});
};
handle_text_input_change = (event) => {
this.props.onChange(event);
this.setState({
text_input_value: event.target.value
});
console.log("withinhandle", this.state.text_input_value);
};
render() {
const {
value,
disabled,
...rest
} = this.props;
const {
input_active
} = this.state;
console.log(input_active);
let input_element_classes = [''];
let inputEmpty = value.length == 0;
console.log("inputempty", inputEmpty);
const inputCompiled = value.length > 0;
if (input_active && !inputEmpty) {
input_element_classes.push('blur');
}
return (
<input {...rest}
className={input_element_classes.join(' ')}
type="text"
ref={this.input_text_ref}
onChange={this.handle_text_input_change}
disabled={disabled}
onBlur={this.blur}
//onKeyDown={this.shouldBlur}
onFocus={this.focus}
/>
);
}
Could someone help me with this? Also, based on input element validation (empty, disabled, the user entering text so on) how can I change the style of the input element. From the code, it's understood that I am using an array of classes (input_element_classes) based on validation I pop the class and push some other class. Is there any other easy way to do this. thanks.
It looks a bit overload. If I got you right, you can write it this way:
export class TextInput extends React.PureComponent {
constructor(props) {
super(props);
this.state = {
isActive: props.value.length > 0
};
}
static defaultProps = {
value: "",
disabled: false
};
onFocus = () => {
this.setState({ isActive: true });
};
onBlur = ({ target }) => {
this.setState({ isActive: target.value.length > 0 });
};
render() {
const { disabled, ...rest } = this.props;
const { isActive } = this.state;
return (
<input
{...rest}
className={`text-input ${isActive ? "active" : ""}`}
type="text"
disabled={disabled}
onBlur={this.onBlur}
onFocus={this.onFocus}
/>
);
}
}
You can find the example in the sandbox https://codesandbox.io/s/zl9mmvmp33

Resources