Radio button not working - reactjs

I have created a radio component but when clicked it does'nt show checked
here is the code
import React from 'react';
import classnames from 'classnames';
const RadioButton = (field) => {
const inputClasses = classnames('form-group has-feedback ',{
'has-error': field.meta.touched && field.meta.error,
});
return(
<div className={inputClasses}>
<label className="radio-inline custom-radio nowrap">
<input
disabled={field.disabled}
type="radio"
name={field.input.name}
value={field.input.value}
defaultChecked={field.defaultChecked}
{...field.input}
/>
<span>{field.label}</span>
</label>
</div>
);
};
export default RadioButton;
here is the field:
<Field
label="True"
component={RadioButton}
name="True"
type="radio"
value={true}
defaultChecked={ true }
/>
<Field
label="False"
component={RadioButton}
name="False"
type="radio"
value={false}
defaultChecked={ false }
/>
this is the warning i am getting on console:
Warning: RadioButton contains an input of type radio with both checked and defaultChecked props. Input elements must be either controlled or uncontrolled (specify either the checked prop, or the defaultChecked prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props
can anyone help me out with this?

You should take a look at the official documentation, specifically the sections regarding Controlled Components and Uncontrolled Components.
Controlled Component
Basically, with controlled components you let React manage the value of said element.
An input form element whose value is controlled by React in this way is called a "controlled component".
To create a controlled component you need a state variable which stores its value, as well as a function which mutates its value based on some event (click, input, etc).
Here's a simple example:
class ControlledComponentDemo extends React.Component {
constructor() {
super();
this.state = {
input: "",
radio: null,
checkbox: []
};
}
changeInput = (e) => {
this.setState({input: e.target.value});
}
changeRadio = (id) => {
this.setState({radio: id});
}
changeCheckbox = (id) => {
let arr = this.state.checkbox.slice();
if(arr.indexOf(id) >= 0) {
arr.splice(arr.indexOf(id), 1);
} else {
arr.push(id);
}
this.setState({checkbox: arr});
}
render() {
return(
<form>
<input type="text" value={this.state.input} onChange={this.changeInput} />
<br /><br />
<input type="radio" name="myRadio" checked={this.state.radio === 0} onChange={this.changeRadio.bind(this, 0)} />
<input type="radio" name="myRadio" checked={this.state.radio === 1} onChange={this.changeRadio.bind(this, 1)} />
<br /><br />
<input type="checkbox" name="myCheckbox" checked={this.state.checkbox.indexOf(0) >= 0} onChange={this.changeCheckbox.bind(this, 0)} />
<input type="checkbox" name="myCheckbox" checked={this.state.checkbox.indexOf(1) >= 0} onChange={this.changeCheckbox.bind(this, 1)} />
</form>
);
}
}
ReactDOM.render(<ControlledComponentDemo />, document.getElementById("app"));
<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="app"></div>
Uncontrolled Component
As the name suggests, in uncontrolled components React does not manage the value of the form elements. Instead, these are managed by the DOM directly the "traditional way".
In a controlled component, form data is handled by a React component. The alternative is uncontrolled components, where form data is handled by the DOM itself.
Create an uncontrolled component is easy:
class UncontrolledComponentDemo extends React.Component {
render() {
return(
<form>
<input type="text" />
<br /><br />
<input type="radio" name="myRadio" />
<input type="radio" name="myRadio" />
<br /><br />
<input type="checkbox" name="myCheckbox" />
<input type="checkbox" name="myCheckbox" />
</form>
);
}
}
ReactDOM.render(<UncontrolledComponentDemo />, document.getElementById("app"));
<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="app"></div>
The issue with your code is that you have a mixed syntax of controlled and uncontrolled components.
In controlled components the value is defined in the state and passed into the value or checked props (depending on the input type) as I demonstrated above.
Since uncontrolled components are not managed by the state we shouldn't pass anything in to the value or checked props either. It doesn't make sense to do that because the DOM manages that on its own.
What we can do though is tell the DOM the initial value of said element. For example a text input could have something already typed in, or a checkbox already checked. We do this with the defaultValue prop.
And this is the mixup that you have done. You are using both defaultValue and checked here. Hence the warning:
Warning: RadioButton contains an input of type radio with both checked and defaultChecked props. Input elements must be either controlled or uncontrolled (specify either the checked prop, or the defaultChecked prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props.
I should also mention that controlled components are the ones recommended by React. You should still read the documentation sections I linked above.

Please use this!
It's working perfectly!
<label>
<input type="radio" defaultChecked={true} disabled={false} value={YOUR_Value} />
{this.state.content}
</label>

Related

React can not use conditionally rendering on a component due to variables being nested inside of my form

I want to conditionally render a component in this case if the user submits a wrong answer, the input is stored as a javascript object called data and gets converted to a string called userInput.
After looking around, I got recommended to create a conditional rendering with a state outside of the form, but the problem I ran across is that since the variables are initialized inside of my form, i can't use ternaries to conditionally render my component in so I'm a bit stuck in what to do.
<main class="gameSection">
<h1>Welcome to League of Wordle!</h1>
<form
onSubmit={handleSubmit((data) => {
let userInput = data.guess;
console.log(userInput);
const championList = Object.keys(champions);
if (userInput.valueOf().toUpperCase() !== correctChampion.valueOf().toUpperCase()) {
<Wrong text="Class" alt="wrong img" img={wrong} />
}
})
}
>
<input
{...register("guess")} class="guess_input" placeholder="Enter Champion Name Here" type="text" />
<input class="guess_input" type="submit" />
</form>
</main>
I suggest you create a state to track if any answers submitted is wrong.
const [isWrong, setIsWrong] = useState(false)
Now, after each submit, update isWrong's value based on input.
onSubmit={handleSubmit((data) => {
let userInput = data.guess;
console.log(userInput);
const championList = Object.keys(champions);
if (userInput.valueOf().toUpperCase() !== correctChampion.valueOf().toUpperCase()) {
setIsWrong(true)
}
else {setIsWrong(false) } // logic in case of correct answer
})
}
Finally, you can implement conditional rendering:
<main class="gameSection">
<h1>Welcome to League of Wordle!</h1>
<form
...
>
<input
{...register("guess")} class="guess_input" placeholder="Enter Champion Name Here" type="text" />
<input class="guess_input" type="submit" />
{isWrong && <Wrong text="Class" alt="wrong img" img={wrong} /> }
</form>
</main>

In this basic react application, why does the custom component `TextInput` allow me to type stuff in even though the regular `input` field doesn't?

I have a basic react form that I am testing out currently. It's still incomplete, but I have discovered unexpected behaviour.
The regular input field doesn't allow me to type in anything, as I am not updating the state yet. However, my custom TextInput component does allow me to type stuff in... Surprising, as I said before, I am not using setValues to update the state yet.
import React, { useState } from 'react';
const App = () => {
const [values, setValues] = useState({
firstName: '',
lastName: ''
});
return (
<div>
<form>
{/* [EXPECTED] this doesn't allow anything to be typed in at the front-end... which is expected...
... as I am not using `setValues` to update the state yet */}
<input
type="text"
id="first-name"
name="firstName"
value={values.firstName}
/>
{/* [NOT EXPECTED] this does allow stuff to be typed in at the front-end... which is strange...
... as I am not using `setValues` to update the state yet */}
<TextInput
id="last-name"
name="lastName"
value={values.lastName}
/>
<button type="submit">
Register
</button>
</form>
</div>
);
};
const TextInput = props => {
return (
<input
type="text"
id={props.id}
name={props.name}
/>
/* <span id={props.id + '-error'}>{props.title}</span> */
);
};
export default App;
Can anybody help me to explain why the difference?
Your first input is controlled - it has a value prop which is used to determine what the value of the element should be when rendered:
<input
type="text"
id="first-name"
name="firstName"
value={values.firstName}
/>
No matter what you type into it, since it's "controlled", the value that exists in it will always be what's currently in state as values.firstName.
In contrast, your second input is uncontrolled. It has no value prop:
<input
type="text"
id={props.id}
name={props.name}
/>
So, since you're not giving React any directives on what its value should be while being rendered, you can type whatever you want into it, and it won't be in conflict with React state.

Retrieve form input and use it within a string

I am trying to take input values from a form and output the results within a string. I don't want to use a database to do so.
Is this possible? Do I have to run the variables through a function? If so how can I go about it?
I'm new to react so providing pseudo-code could possibly make this more difficult than it needs to be but I will do my best.
<div className="form">
<form
name="contact"
method="POST"
>
//variable name
<input name="name" placeholder="Your Name" type="text" />
//variable age
<input name="age" placeholder="Your Age" type="number" />
//submit
<button>Send</button>
</form>
</div>
Based on the form above I expect to be able to somehow fetch the input values in the form after submit and have them display within a string.
Ex: Your name is "name" and your age is "age".
The result would be displayed on the same page if possible.
Thank you in advance for any help provided.
I could write you a bunch of theories, facts, and opinion-based statements.
Instead of that, I've chosen to write down the code. Look at the comments for more insight into the workflow, and if you have any questions, I'll be here to provide help.
Run the code snippet and see ti in action.
class FormComponent extends React.Component {
constructor(props) {
super(props);
this.state = {name: '', age: null, submitted: false}; // Here we're saving our input values
}
// Let's handle the input changes
// This is a great approach, since we don't need to write multiple 'onChange' handlers.
// Depending on what's the current 'name' of the input, we're assigning the currently entered value.
// We're accessing it via the 'e' -event parameter that's automatically passed to us
handleChange = (e) => {
this.setState({[e.target.name]: e.target.value});
}
// This is our onSubmit handler
handleSubmit = (e) => { // same e parameter
const { name, age, submitted } = this.state; // here we're doing a bit od es6 destructuring
// Instead of showing that 'alert' we'll change the 'submitted' part of the state to true. This check is going to be useful when we come to the part where we want to check if the user has clicked the button if YES, this part will be equal to true and we'll show them the output if not, nothing will be shown.
// alert(`Your name is ${name} and you're ${age} years old`);
this.setState({ submitted: true });
e.preventDefault();
}
render() {
// Here we're doing that destructuring again.
// So, later on we can use e.g. 'name' inseatd of 'this.state.name'
const { name, age, submitted } = this.state;
return (
<div>
<form onSubmit={this.handleSubmit}>
<label>
Name:{' '}
<input
/* This the above used 'name' property -> e.target.name */
name='name'
type="text"
/* Setting the current value from the current
state value and making this into a controlled
form which is what we want 99% of the time */
value={this.state.name}
/* Here we are passing in a reference to our
'handleChange' functions to the built-in
'onChange' method */
onChange={this.handleChange}
required />
</label>
<br />
<br />
<label>
Age:{' '}
<input name="age"
type="number"
value={this.state.age}
onChange={this.handleChange}
required />
</label>
<br />
<br />
<input type="submit" value="Submit" />
</form>
<br />
{/* Here will be our output. What we're doing here is checking if the FORM was submitted.
//If that's true then we want to show our newly created string, but if not, we don't want to show anything in that case -> 'null' */}
{submitted ? <p>{`Your name is ${name} and you are ${age} years old.`}</p> : null}
</div>
);
}
}
ReactDOM.render(
<FormComponent />,
document.body
);
<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>

How to link a text field with a radio button

Before Clicking anything text field should be disable . when after the radio button selected my text field must be enable.
This is the working solution of your question.
class App extends React.Component {
state = {
isRadioSelected: true
};
changeHandler = () => {
this.setState({ isRadioSelected: false });
};
render() {
return (
<div className="App">
<h3>Input text is {this.state.isRadioSelected ? 'Disabled': 'Enabled'}</h3>
<input type="text" disabled={this.state.isRadioSelected} />
<br />
<label>Select Radio Button</label>
<input type="radio" onChange={this.changeHandler} />
</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' />
Your description is pretty vague and you don't have any code samples, but here's likely what you want to do:
Make the radio button a controlled component, so that you can access it's value within React's state.
Tie the input's disabled attribute to the value of that state field.
It also seems like you want a checkbox, and not a radio button, since a radio button cannot be untoggled if there is only a single radio button.
This code will likely not work as-is (I haven't run it), but should provide a starting idea:
function Tester() {
const [radioValue, setRadioValue] = useState(false)
return (
<div>
<input type="radio" onClick={(e) => setRadioValue(e.target.value)} value={radioValue} />
<input type="text" placeholder="your input box" disabled={!radioValue} />
</div>
)
}

How to make react semantic UI TextArea with default value, but still allows user to change the value?

I have tried using defaultValue and value in TextArea but it wont allow user to change the value.
The parent div of the textarea is redux-form Field. And try to pass the value stored in redux state to the textarea
<Field
name="message"
component={renderField}
...
onChange={ (e: any) =>
triggerHoldResponse(e.target.value, conversation.id)
}
/>
const renderField = ({input, type, meta: { error }}: any) => (
<div>
<TextArea
className={styles.textarea}
{...input}
placeholder={placeholder}
type={type}
/>
<div className={styles.errorSignal}>
{error}
</div>
</div>
);
SUI TextArea is base class for Form.TextArea, and both uses the same prop value for setting the default Text Value for the textarea.
Following Code works for me:
import React from 'react'
import { Form, Input, TextArea, Button } from 'semantic-ui-react'
const FormTextAreaExample = () => (
<Form
<Form.TextArea
autoHeight
onChange={this.handleMessageChange}
label="Message"
value={mesg}
placeholder="Enter your request message"
rows={3}
/>
</Form>
)
export default FormTextAreaExample;
Where value={mesg}, sets the default state of textarea (is set).
If you are using Semantic UI react you can use a Form.Field tag
You can set a default value and do what you are asking by using
"defaultValue='default text you are trying to display'
You can see a Form.Field Example below.
<Form>
<Form.Field
name="description"
required control={TextArea}
width={8}
onChange={this.handleChange}
label="Event Description"
defaultValue="Default text..."
type="text"
placeholder="Describe your event!"/>
</Form>
Note: defaultValue will override your placeholder and the defaultValue will not be removed when the click on textarea.
If you want to just display info of what the textarea is for I would use placeholder.
You can link the value of the Textarea input to that of a value from state such that you can set the default text for the text but also allow for the state to be updated in turn updating the value. You can accomplish this using linkstate.
Also if you already have the date in in your store you can set it up on the ComponentDidMount lifecycle event. to set the value of the linked state value therefore setting a default value.
Example usage from the docs:
import linkState from 'linkstate';
class Foo extends Component {
state = {
text: ''
};
render(props, state) {
return (
<input
value={state.text}
onInput={linkState(this, 'text')}
/>
);
}
}
https://github.com/developit/linkstate
An alternative way is to use the textarea tag since I was not able to find proper solution
example:
<label className="wps-label">Message</label>
<textarea
name="message"
placeholder='Your message'
onChange={(e)=> setMessage(e.target.value)}
>
{message}
</textarea>
<Form.Checkbox
name='show_tooltip'
label='Show popup or tooltip when hovering over the spoiler'
value='yes'
onChange={onChange}
defaultChecked={data?.show_tooltip}
/>
or via react-final-form
<Form
initialValues={{
title: modalView === 'add' ? '' : data?.title?.rendered,
content: modalView === 'add' ? '' : data?.content?.rendered
}}
...

Resources