Reset input filed onSubmit redux-form - reactjs

I am trying to dispatch reset using ref from Redux form example given on their site but failing in the process given is the code which I am trying to implement :
import {reset} from 'redux-form';
import {connect} from 'react-redux';
const DCTForm = ({ handleSubmit, onSubmit }) => (
<section className="chat-bg">
<form className="chatBoxForm" onSubmit={handleSubmit(onSubmit)} >
<section className="input_container">
<Input
name="message"
type="text"
/>
<img src={Arrow_up} className="icon-static input_img" alt="Arrow_up" />
<img src={Paper_plane} className="icon-static input_img_2" alt="Paper_plane" />
</section>
</form>
</section>
);
DCTForm.propTypes = {
handleSubmit: PropTypes.func,
onSubmit: PropTypes.func
};
DCTForm.defaultProps = {
handleSubmit: noop,
onSubmit: noop
};
const mapDispatchToProps = dispatch => {
return {
reset:(dct)=>dispatch(reset('DCTForm'))
}
}
export default connect(null,mapDispatchToProps)(reduxForm({form: "DCTForm"})(DCTForm);
Thanks in Advance :)

I suggest to use single source of truth for the input fields . instead of using refs .Use onChange event handler and this onchange event handler should set the sate attribute which contains the value of the input field .Moreover, set value attribute of the input field to be this.state.inputField (what ever input field is)
input tag
event
State

Related

Custom react hook to set input form not working

I've tried creating a custom hook, following the examples an article about handling forms in react using hooks. I should also add I'm very new to react.
This is the content of hooks/useInput.js:
import { useState } from "react";
function useInput(initialValue) {
const [value, setValue] = useState(initialValue);
function handleChange(event) {
console.log(event.target.name);
console.log(event.target.value);
setValue(event.target.value);
}
return [value, handleChange];
}
export default useInput;
In a component I have the following:
import useInput from "hooks/useInput";
export default function Address(props) {
const [fullName, setFullName] = useInput("");
return (
<FormControl fullWidth>
<CustomInput
required
labelText="Full name"
id="fullName"
formControlProps={{
fullWidth: true
}}
value={fullName}
onChange={setFullName}
/>
</FormControl>
);
}
When I try to input some text (or even if I try to change the default state), nothing happens.
Any breakpoint that I set in useInput.js are not hit and no logging appears in the console.
Where am I going wrong?
If you want to see your current input value with a button click you can see like this. I didn't even change your userInput.js file. I can see the updated value by doing this and console as well.
export default function Address(props) {
const [fullName, setFullName] = useInput("");
return (
<>
<input
placeholder="Name"
value={fullName}
onChange={setFullName}
/>
<button onClick={() => {
console.log(fullName);
}}>Submit</button>
</>
);
}
Since I don't know about your CustomInput, I have written this with default input and button. Please check your CustomInput correctly. Because default input is working.

Disable submit button if field is empty

I have a React app using hooks and trying to figure out how to keep a submit button disabled if the search field is empty.
Assuming a regular form field with submit button, how can I set a state hook that keeps the search button disabled until the user inputs text. I assume there should be an onChange function that probably updates the state on input change, but not exactly sure of the implementation.
const [disabled, isDisabled] = useState(true);
<input type="text" id="q" name="q" placeholder="Search.." name="search">
<button type="submit"><i class="fa fa-search"></i></button>
If you want to disable a button when an input string is empty, then the only state you need is the value of the input string.
const [inputVal, setInputVal] = useState('')
// ...
<input value={inputVal} onChange={e => setInputVal(e.target.value)} />
// ...
<button disabled={!inputVal}> /* ... */ </button>
Here we connect the input component to the state value. This is called a controlled component, because its value is controlled from by an external source (the state value) as opposed to an uncontrolled component, which means the input element holds it's own internal state (the default way inputs work if you don't set their value prop directly.
When the input component receives input (such as someone typing a character) the onChange prop is called. All we do then is take the new value of the input element (e.target.value) and use it to set the state.
If you can derive state from other state, then you shouldn't be storing it in state. Having a state variable called disabled only makes things more complex. The general idea is to use as little state as possible, and compute as much as you can from that state.
Please check this complete example where I used class component and use a disable property under state object. When you write something on textbox, the disable property will be set as false.
import React from "react";
export default class Login extends React.Component {
constructor(props) {
super(props);
this.state = {disable: true};
}
handleChange = (event) => {
this.setState({disable: event.target.value === ''})
};
render() {
return (
<div>
<div>
Name: <input onChange={this.handleChange}/> <br/>
<button disabled={this.state.disable} >Login</button>
</div>
</div>
);
}
}
here is the same example of functional component
import React, {useState} from "react";
export default function Login() {
const [disable, setDisable] = useState(true);
function handleChange(event) {
setDisable(event.target.value === '');
}
return (
<div>
<div>
Name: <input onChange={handleChange}/> <br/>
<button disabled={disable}>Login</button>
</div>
</div>
);
}

Redux Form wrapper for kendo-react-ui Input error

I am using react-kendo-ui. I want to wrap Input from #progress/kendo-react-inputs to use it with ReduxForm. Please find my code below:
import React from 'react'
import { Input } from '#progress/kendo-react-inputs';
const InputText = ({ input, label, type, meta: { touched, error } }) => (
<div>
<label>{label}</label>
<div>
<Input {...input} type={type} placeholder={label} />
{touched && error && <span>{error}</span>}
</div>
</div>
)
export default InputText
Call the InputText from another component as below:
import React from 'react';
import { Field, reduxForm } from 'redux-form';
import { Input } from '#progress/kendo-react-inputs';
import InputText from './input-text';
const validateNotEmpty = value => !value ? 'Must enter a value' : null;
const onSubmit = (values) => {
console.log(values);
}
const AddLoc= ({ handleSubmit }) => (
<form onSubmit={handleSubmit}>
<div>
<Field
label="Address"
name="address"
component={InputText}
validate={validateNotEmpty}
/>
</div>
<button type="submit">Submit</button>
</form>
)
export default reduxForm({
form: 'AddLoc'
})(AddLoc)
But while typing inside the input text it keeps giving the following error/warning:
Warning: This synthetic event is reused for performance reasons. If you're seeing this, you're accessing the property `nativeEvent` on a released/nullified synthetic event. This is set to null. If you must keep the original synthetic event around, use event.persist().
While typing inside the input text automatically outputs [object Object]. Please check the image above. Could anyone please let me know what is causing the error.
Thanks
The reduxForm works only with pure DOM <input />. Internally it clones the elements search the children and then attaches the onChange dynamically. So it will not work with the Input and the NumericTextBox from the #progress/kendo-react-inputs package. This statement is based on the official kendo documentation about integrating with the redux-form.
The same author of the redux-form have fork of it called react-final-form which could be used on any component that have Value and onChange props. By our tests it works with the components from #progress/kendo-react-inputs and #progress/kendo-react-dropdowns packages. It looks kendo already have an example using final-form in their integration section.

ReactJS - Redux Form - how to conditionally show/hide element based on radio Field element?

I'm relatively new to Redux and I have a form that has some radio inputs "Yes" or "No". Basically, I want to conditionally show another element which contains another redux form field, based on that radio input selection. Is there a straight forward to do this?
I'm trying to just check the formProps.site_visit value, but I get an error about it being undefined. For the record, I've greatly reduced the amount of code in this component for brevity sake.
export class RequestForm extends React.Component {
submit(formProps) {
const request = {
square_footage: formProps.get('square_footage'),
site_visit: formProps.get('site_visit'),
};
this.props.dispatch(createRequest(request));
}
// Redux Form Props.
const { handleSubmit, pristine, reset, submitting } = this.props
return (
<form className="page-form__wrapper">
<div className="page-form__block">
<div className="page-form__block">
<p> Is a site visit required to complete this request? </p>
<Field name="site_visit"
component={RadioButtonGroup}
>
<RadioButton value="true" label="Yes" />
<RadioButton value="false" label="No" />
</Field>
</div>
{this.formProps.site_visit === true &&
<div className="page-form__block">
<p> Estimate the total area of work in square feet </p>
<Field name="square_footage" component={TextField} hintText="Square Feet" />
</div>
}
</div>
</form>
);
}
Thanks in advance!
You'll need to use a formValueSelector
const selector = formValueSelector('formName');
function mapStateToProps(state, props) {
const isChecked = selector(state, 'checkboxField');
return { isChecked };
}
connect using mapStateToProps
the render method will look like this.
render() {
return (
{ this.props.isChecked && (
<div>
this only shows up if the checkboxField Field is checked
</div>
) }
);
}
edit:
looks like you're using reselect - I've never used createStructuredSelector and I don't 100% understand the documentation, but a possible solution might be:
const mMapStateToProps = createStructuredSelector({
request: selectRequestForm(),
user: selectUser()
});
const mapStateToProps = (state, props) => {
return {
isChecked: selector(state, 'checkboxField'),
... mMapStateToProps(state, props) // not sure if createStructuredSelector accepts a props param
}
};
that'll compose the two. I think you could also use createSelector with mMapStateToProps and the mapStateToProps I originally posted...

Range bar in redux form

i have a range bar which i create from react-slider. I want to use it in a redux-form. My problem is that the values are not returning. To be more specific when i sumbit my form the other fields return values while this range bar returns undefined. How do i have to use the Range in a redux-form?? My code is
<FormGroup className="col-sm-3 ">
<Label for="value-slider">VALUE</Label>{' '}
<Field
id="value-slider"
name="value-slider"
component={Range}
/>
</FormGroup>
You cannot pass any random component to component prop. It must implement interface of redux-form (see usage), what Range does not. In short, passed element must at least trigger event with input.onChange and display value from input.value prop:
const MyRange = props => (
<Range value={props.input.value} onChange={props.input.onChange} />
)
And then use it:
<Field
id="value-slider"
name="value-slider"
component={MyRange}
/>
I've run into this issue just now, thanks to maddox2 for the answer which set me along the right lines, however, as one user pointed out in the comments above, the solution above will give TypeError: value.map is not a function.
To fix this, you need to explicitly set the type of the field in initialValues, when you use reduxForm()to create the form. Example code is below.
Note how additional props used by Range are also passed to ReduxRange in the props prop, and that these are then passed down to the Range in the wrapping component.
import React from 'react';
import { Field, reduxForm } from 'redux-form'
import Range from 'rc-slider/lib/Range';
import 'rc-slider/assets/index.css';
// initial wrapper - note alterations
const ReduxRange = props => {
const { input: { value, onChange } } = props
return (
<Range
value={props.input.value}
onChange={props.input.onChange}
{...props}
/>
)
}
// the form
export const SomeReduxForm = props => {
const { handleSubmit } = props;
// these props will get passed to the Range
const rangeProps = {
defaultValue:[2020, 2040],
marks:{
2020: '2020',
2030: '2030',
2040: '2040',
2050: '2050',
2060: '2060',
2070: '2070',
2080: '2080',
},
pushable:true,
allowCross:false,
min:2018,
max:2080,
step:1,
}
return (
<section className="box box-default">
<form>
<div className="box-header">Year Range</div>
<div className="box-body">
<Field
name="yearRange"
component={ReduxRange}
props={rangeProps}
/>
</div>
</form>
</section>
)
}
export default reduxForm({
form: 'someReduxForm',
initialValues: {
yearRange: [2020, 2040]
}
})(SomeReduxForm)

Resources