Redux Form: Input stays with 'touched: false'
Asked Answered
T

3

7

Wanted to validate my inputs and change the CSS depending of the user interaction.

Starting with a required validation method I wrap all my inputs component with a <Field> and pass to validate an array of func. Just required for now.

But for all my fields the value stay the same touched: false and error: "Required". If I touch or add stuff in the input, those values stay the same.

Validation

export const required = value => (value ? undefined : 'Required')

NameInput

import React from 'react';
import { Field } from 'redux-form'
import InputItem from 'Components/InputsUtils/InputItem';
import { required } from 'Components/InputsUtils/Validation';

const NameInput = () => (
  <Field
    name={item.spec.inputName}
    type={item.spec.type}
    component={InputItem}
    validate={[required]}
    props={item}
  />
);

export default NameInput;

InputItem

import React from 'react';

const InputItem = ({ spec, meta: { touched, error } }) => {        
  const { type, placeholder } = spec;
  return (
    <input
      className="input"
      type={type}
      placeholder={placeholder}
    />
  );
};

export default InputItem;
Tortoiseshell answered 20/3, 2018 at 16:54 Comment(0)
D
4

The redux-form controls its own props within your <input /> element as long as you use the spread operator to pass those props into your input.

For example, where you are doing const InputItem = ({ spec, meta: { touched, error } }) => ...

Try destructing the input from the Component: const InputItem = ({ input, spec, meta: { touched, error } }) => ...

And where you have your <input ... />, try doing the following:

<input
  {...input}
  className="input"
  type={type}
  placeholder={placeholder}
/>

The redux-form captures any onBlur and onChange events and uses its own methods to change the touched state. You just need to pass those along as shown above.

These are what you need: https://redux-form.com/7.1.2/docs/api/field.md/#input-props

Dunton answered 20/3, 2018 at 18:31 Comment(2)
Thank I miss this props. Now I have another issue. If I lose focus without the requirement (a simple value) I add a red check icone. But If I focus again then add something the icon doesn't change even if error's value goes to undefined. See my EDIT.Tortoiseshell
That's odd, seems like your code should work fine. Does you see the '----Undefined-----' in your console?Dunton
A
11

There are 2 solutions to solve the "touched is always false" issue.

1) Ensure that input.onBlur is called in your component

For an input:

const { input } = this.props

<input {...input} />

For custom form elements without native onBlur:

const { input: { value, onChange, onBlur } } = this.props

const className = 'checkbox' + (value ? ' checked' : '')

<div
  className={className}
  onClick={() => {
    onChange(!value)
    onBlur()
  }}
/>

2) Declare your form with touchOnChange

const ReduxFormContainer = reduxForm({
  form: 'myForm',
  touchOnChange: true,
})(MyForm)
Alemanni answered 24/1, 2019 at 23:19 Comment(0)
D
4

The redux-form controls its own props within your <input /> element as long as you use the spread operator to pass those props into your input.

For example, where you are doing const InputItem = ({ spec, meta: { touched, error } }) => ...

Try destructing the input from the Component: const InputItem = ({ input, spec, meta: { touched, error } }) => ...

And where you have your <input ... />, try doing the following:

<input
  {...input}
  className="input"
  type={type}
  placeholder={placeholder}
/>

The redux-form captures any onBlur and onChange events and uses its own methods to change the touched state. You just need to pass those along as shown above.

These are what you need: https://redux-form.com/7.1.2/docs/api/field.md/#input-props

Dunton answered 20/3, 2018 at 18:31 Comment(2)
Thank I miss this props. Now I have another issue. If I lose focus without the requirement (a simple value) I add a red check icone. But If I focus again then add something the icon doesn't change even if error's value goes to undefined. See my EDIT.Tortoiseshell
That's odd, seems like your code should work fine. Does you see the '----Undefined-----' in your console?Dunton
S
1

Another point to consider: I passed {...props} to my custom component, however, touched still remained false. That is because although props contained the input object, my component couldn't deduce onBlur from it. When explicitly stating <CustomComponent {...this.props} onBlur={this.props.input.onBlur}, it worked as expected.

Steadfast answered 18/10, 2020 at 9:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.