[React 15.2.0] Additional props warning #1249

Closed
erikras opened this Issue Jun 30, 2016 · 84 comments

Comments

Projects
None yet
Owner

erikras commented Jun 30, 2016

It will be interesting to see, when React 15.2.0 is released, how many of these warnings redux-form generates. More info and discussion here from the page the warning links to:


The unknown-prop warning will fire if you attempt to render a DOM element with a prop that is not recognized by React as a legal DOM attribute/property. You should ensure that your DOM elements do not have spurious props floating around.

There are a couple of likely reasons this warning could be appearing:

  1. Your component is transferring its own props directly to a child element (eg. https://facebook.github.io/react/docs/transferring-props.html). When transferring props to a child component, you should ensure that you are not accidentally forwarding props that were intended to be interpreted by the parent component.
  2. You are using a non-standard DOM attribute, perhaps to represent custom data. Custom data attributes should always have a data- prefix, as described in https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_data_attributes
  3. React does not yet recognize the attribute you specified. This will likely be fixed in a future version of React. However, React currently strips all unknown attributes, so specifying them in your React app will not cause them to be rendered.

Props like valid, invalid, dirty, and pristine might cause warnings for cases where someone is just destructuring the field object into an input, i.e. <input type="text" {...firstName}/>.

Collaborator

ooflorent commented Jul 1, 2016

I'm affraid this change will lead to a massive amount of issues created here... Unfortunately we can't do much to prevent this. One solution in v6 is to provide a new input component.

const InputProps = [
  // HTML attributes
  "placeholder",
  "type",
  "value",
  // Event listeners
  "onBlur",
  "onChange",
  "onFocus",
]

const InputWrapper = props => 
  React.createElement("input", _.pick(props, InputProps))

export default InputWrapper

And to make it the default component of Field:

Field.defaultProps = {
  component: InputWrapper,
}

@ooflorent ooflorent added the discussion label Jul 1, 2016

Collaborator

ooflorent commented Jul 1, 2016

Another workaround is to instrument component if it is passed as a String (input or select).

Owner

erikras commented Jul 1, 2016

Results of first test:


Warning: Unknown propsactive,dirty,error,invalid,onUpdate,pristine,touched,valid,visited,asyncValidatingon <input> tag. Remove these props from the element. For details, see https://fb.me/react-unknown-prop


It's amusing how accustomed whoever wrote that warning message is with GitHub Markdown that they used backquotes.

Owner

erikras commented Jul 1, 2016

What if you could do something like this:

import { reduxForm, Field, filterProps } from 'redux-form'

const renderTextField = field => 
  <div>
    <input type="text" {...filterProps(field)}/>
//                         ^^^^^^^^^^^
    {field.touched && field.error && <div>{field.error}</div>}
  </div>

const MyForm = props =>
  <form onSubmit={props.handleSubmit}>
    <Field name="whatever" component={renderTextField}/>
  </form>
export default reduxForm({ form: 'myForm' })(MyForm)

Seems like the least a library designed to destructure objects into dom components could do...

Contributor

gaearon commented Jul 1, 2016

Maybe pickDOMProps to make it clearer what it does.

Is nesting the input-specific props an option? eg.

{
  input: {
    active
    autofill
    checked
    onBlur
    onChange
    onDragStart
    onDrop
    onFocus
    onUpdate
    value
    visited
  }
  autofilled
  dirty
  error
  initialValue
  invalid
  name
  pristine
  touched
  valid
}
Owner

erikras commented Jul 2, 2016

@tylergoodman That is an option, yes.

@jambonrose jambonrose referenced this issue in Hacker0x01/react-datepicker Jul 2, 2016

Closed

React 15.2 Unkown Prop Warning #517

Contributor

gaearon commented Jul 2, 2016

@tylergoodman’s suggestion looks cleanest.

Owner

erikras commented Jul 2, 2016

@gaearon Stinks of "breaking change", though.....

Contributor

gaearon commented Jul 2, 2016

You could..

  1. Add input to both v5 and v6 without removing old props
  2. Remove old props in v6 final
Owner

erikras commented Jul 4, 2016

Ooh, for a moment there, I thought I might be clever and make the redux-form metadata props (touched, pristine, error, etc.) not enumerable on the props object. That way they would not be copied when destructuring into the input component. Turns out React.createElement is enumerating through them, so they don't get through. Oh well...

Contributor

gaearon commented Jul 4, 2016

Nah, smart tricks are only going to make things worse. Please fix the underlying issue. 😉

Owner

erikras commented Jul 4, 2016

I wasn't too fond of it it originally, but after implementing it, @tylergoodman's suggestion is growing on me.

const renderField = field => (
  <div>
    <label>{field.input.placeholder}</label>
    <div>
      <input {...field.input}/>
      {field.touched && field.error && <span>{field.error}</span>}
    </div>
  </div>
)

The important thing is that the passthrough props go into the input key.

<Field name="username" component={renderField} type="text" placeholder="Username"/>
//                           Those guys --->   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Contributor

gaearon commented Jul 4, 2016

Yea, IMO it’s the most elegant and clean solution. 👍

Owner

erikras commented Jul 4, 2016

One unfortunate consequence is that redux-form worked "out of the box" with many third party input widgets, where you could just say

<Field name="color" component={DropdownList} data={colors}/>

Where as now, you have to pull the input props out for it with a:

const renderDropdownList = field => <DropdownList {...field.input}/>
...
<Field name="color" component={renderDropdownList} data={colors}/>

😢

jimbolla commented Jul 4, 2016

@erikras Seems like there's 3 possible behaviors:

  1. component = dom: should only get {...field.input}
  2. component = component that wants flat: should get {...field} {...field.input}
  3. component = component that wants nested: should get {...field}

You could handle this with extra props on <Field>. Ex:

  <Field name="name" component="input"> <!-- autodetects dom=true because string, same as: ->
  <Field name="name" component="input" dom>

  <Field name="color" component={DropdownList} data={colors} flat /> <!-- flat tells Field to spread field.input -->
Owner

erikras commented Jul 4, 2016

@jimbolla Excellent thinking! I've already implemented 1 and 3, but I definitely see some value in a flat prop that would get around the field => <DropdownList {...field.input}/> silliness. Thanks for that.

Contributor

gaearon commented Jul 4, 2016

flat and dom seem like very magic solutions to me.
They might make sense today in the context of “how do I get rid of this warning?”
I’m not sure they would make sense in a year for people reading the code using Redux Form.

One unfortunate consequence is that redux-form worked "out of the box" with many third party input widgets, where you could just say

This pattern is problematic and can lead to bugs. If third party DropDownComponent adds a field called error (new feature—minor per semver), your app would suddenly start passing Redux Form errors to it, and potentially crash or lead to unexpected behavior. This doesn’t seem like a pattern you’d want to encourage.

I think being explicit about the props that are passed is the way to go -- everything else in react/redux tends to be explicit in the same way. (A good thing, IMO.) Making those props available on field.input makes a lot of sense to me.

Before I found redux-form and I was starting to roll my own, an input sub-prop was what I came up with. So if I'm anything close to normal and a single piece of anecdotal evidence is worth anything, that's what I'd like to see. :)

yanndinendal commented Jul 5, 2016

What about textareas or selects? For example, field.value is not valid for a textarea.

And even inputs don't have always the same props: checked only exists for some input types.

I getting the very same error , using Redux Form 5.2.5:

app.js:2483 Warning: Unknown propsinitialValue,autofill,onUpdate,valid,invalid,dirty,pristine,active,touched,visited,autofilledon <input> tag. Remove these props from the element. For details, see https://fb.me/react-unknown-prop

is there any way to get rid of this error, by downgrading to specific version of the library for example ?

DimaRGB commented Jul 5, 2016

@padsbanger don't use react v15.2 for redux-form v5.

Or omit all this props from every fields.

Owner

erikras commented Jul 5, 2016

What about textareas or selects? For example, field.value is not valid for a textarea.

And even inputs don't have always the same props: checked only exists for some input types.

@yanndinendal Those are covered by React.

Owner

erikras commented Jul 5, 2016

Published fix in 6.0.0-rc.2.

@erikras erikras closed this Jul 5, 2016

emborg commented Jul 6, 2016

in v6 rc2 have error
Warning: Unknown prop input on tag. Remove this prop from the element. For details, see https://fb.me/react-unknown-prop
in input (created by Unknown)
in div (created by Unknown) ...

in v6 rc1 unknown props was picked with (as suggested above)
const {
active, dirty, error, invalid, onUpdate, pristine, touched, valid, visited,
asyncValidating,
...rest
} = props;

frost555 commented Jul 6, 2016

Found the issue that user defined props are transfered on props.input.

var renderFieldControl = (props) => {
  props.myOnBlur == undefined; //true
  props.input.myOnBlur == undefined; //false
  .....
};
<Field name="field1" myOnBlur={()=>alert('hello world')} component={renderFieldControl}/>

How can i workaround it? As you can see - there is no need to pass myOnBlur prop to input DOM element.
Maybe we should support following API?

<Field name="field1" input={{placeholder:"goes to props.input"}} xyz="goes to props"  component={renderFieldControl}/>
Owner

erikras commented Jul 6, 2016

@frost555 No, that is as designed. It must be that way to get things like placeholder and type passed along to your input.

frost555 commented Jul 6, 2016

Sorry for editing my message.
Would you mind to comment on edited one (my api proposal)?

Owner

erikras commented Jul 6, 2016

@frost555 Maybe. I'd be open to hearing arguments for and against.

Contributor

epeli commented Jul 6, 2016

I'm having hard time migrating from RC1->RC2 because many of my HOCs assumes that the props passed to the Field are in the props attribute directly. It seems that now I have to destructure both props and props.input in every HOC in order to get the props it needs because often I need props from both redux-form (valid, touched etc.) and my custom props passed to the Field.

Alternative to @frost555's proposal would be to make it other way around:

<Field name="field1" containerProps={{myOnBlur: "goes to props"}} xyz="goes to props.input" ...

This would be compatible with RC2.

@joeshub joeshub referenced this issue in gajus/react-css-modules Jul 6, 2016

Closed

react Warning: Unknown prop `styleName` #153

q42jaap commented Jul 7, 2016

Hi @erikras,

I think the docs under props : object [optional] haven't changed yet, It would be nice to give an example like e.g. props.input.className..

q42jaap commented Jul 7, 2016

containerProps like props which go to container instead of input. Maybe rename props to inputProps to be more specific

Like @epeli, I'm also having a difficult time migrating from RC1->RC2. Many of my components can be used independent of a Field. Unfortunately now that Field is obtrusively tampering with props, it prevents props that I want simply relayed from doing so. My components can no longer depend on the incoming props and need to flatten props and props.input before destructuring.

It seems we need some way to specify props that should be relayed (not placed in input). @epeli's suggestion to relay only containerProps and place all other props in input would definitely work in my use case as well.

frost555 commented Jul 7, 2016

Yep, i agree. "containerProps" would be OK for me too.

Is the main reason for "containerProps" just because it's ugly to have that stuff thrown onto the input? It doens't throw the 15.2 warning right?

Owner

erikras commented Jul 7, 2016

Is the main reason for "containerProps" just because it's ugly to have that stuff thrown onto the input?

Yes. If you previously had an input renderer that was like:

renderWidget = ({ mySpecialLabel, ...rest }) =>
  <div>
    <label>{mySpecialLabel}</label>
    <input {...rest}/>
  </div>
// called with
<Field name="whatever" compoenent={renderWidget} mySpecialLabel="Used to go into root"/>

It now has to be:

renderWidget = ({ input: { mySpecialLabel, ...rest } }) =>
//                ^^^^^^^^------ not that big a deal, if you ask me
  <div>
    <label>{mySpecialLabel}</label>
    <input {...rest}/>
  </div>
// called with
<Field name="whatever" compoenent={renderWidget} mySpecialLabel="Now goes into input"/>

You just have to learn:

  1. name, value, and event listeners are under input
  2. All other meta data, like error or touched, is under the root
  3. Additional props passed go under input

It's # 3 that people are complaining about, and I'm certain that should be the default behavior, but I'm not really convinced that adding a special prop name to force values into the root solves much.

I agree that it would be nice if only input-like props (e.g. placeholder) got put into the input, but that would require maintaining a whitelist and I don't want to maintain, and Mr. @gaearon says that's a no-no.

The problem is not that it "looks ugly". The problem is that Field is making assumptions about the props and tampering with them. I understand completely why the input-related props were moved to input; however, the actual problem is that Field has a component specified. The component is responsible for eventually rendering the input, but is not necessarily the input itself. The component should be able to delegate the input props to the input component whenever it is rendering it.

For example, a Field could have a component specified that will render a bootstrap form-group consisting of a label and an error and an input/select/textarea. The FormGroup component in this example may want a label property that is not intended to be passed down to the input. But now the label property is being placed as props.input.label.

So now we lose prop type validation on the individual properties that we're now receiving via input prop on the underlying component right?

Contributor

gaearon commented Jul 7, 2016

input: PropTypes.shape({
  whatever: PropTypes.object,
  whatever2: PropTypes.number
})

?

Owner

erikras commented Jul 7, 2016

@jason-whitted Yes, I agree with all of that. See the mySpecialLabel in my previous comment. That's how that would be done.

@babsonmatt Darn, @gaearon beat me to it.

babsonmatt commented Jul 7, 2016

should have probably looked into that before asking, thanks @gaearon @erikras

jason-whitted commented Jul 7, 2016

I still don't think I've done a good example of explaining the issue.

Here is an example of a FormGroup being used without being nested in a Field.

<FormGroup label="Example" content={props => <b>Example</b>} />

This would render as:

<div className="form-group">
  <label>Example</label>
  <b>Example</b>
</div>

And here is an example being nested in a field.

<Field name="firstName" component={FormGroup} label="Example" content={TextField} />

FormGroup expects label and content props, but Field has decided to put them inside props.input. Now I have to change FormGroup to expect props to support both { label, content } AND { input: { label, content } }. Meanwhile FormGroup doesn't actually care about the input props -- only the TextField component specified by the content prop does.

@jason-whitted so it couples the form component with the redux form way of doing things

Owner

erikras commented Jul 7, 2016

@jason-whitted You're going to need wrapper components. See #1285 (comment).

@erikras thanks

Contributor

jayphelps commented Jul 7, 2016

for those upgrading, onUpdate was also completely removed but was accidentally not documented as a breaking change.

Owner

erikras commented Jul 7, 2016

Oh crap. Sorry about that, @jayphelps. I will modify the release notes. onUpdate was added in this library's infancy to make it work better "out of the box" with Belle. But since the input props got moved in this version, it no longer will work "out of the box" with any UI widget library, so it was removed for clarity.

@erikras

You're going to need wrapper components.

Your proposal is to create a wrapper component to flatten the props and then another wrapper component to rebuild the input props?

Field's component is FormGroup -- which does not care about input props. FormGroup's component is TextField -- which DOES care about input props.

const flattenInputProps = Component => ({ input, ...other }) => <Component {...other} {...input} />;
const unflattenInputProps = Component => ({ 
    autofilled, 
    dirty, 
    error, 
    initialValue, 
    invalid, 
    name, 
    pristine, 
    touched, 
    valid, 
    ...other
  }) => <Component autofilled={autofilled} 
                   dirty={dirty} 
                   error={error} 
                   initialValue={initialValue} 
                   invalid={invalid} 
                   name={name} 
                   pristine={pristine} 
                   touched={touched} 
                   valid={valid} 
                   input={...other} />;
<Field name="firstName" 
       component={flattenInputProps(FormGroup)} 
       label="Example" 
       content={unflattenInputProps(TextField)} />
Owner

erikras commented Jul 7, 2016

@jason-whitted Are FormGroup and TextField from a third party library?

FormGroup and TextField are hypothetical components. I'll stub them out as an example.

// NOTE: FormGroup has no dependency on Field (or any knowledge of redux-form for that matter)
const FormGroup = ({ label, content: Content, ...other }) => (
  <div className="form-control">
    <label>{label}</label>
    <Content {...other} />
  </div>
);
// NOTE: TextField on the other hand is aware of redux-form and is trying to pass on the input props.
const TextField = ({ input, ...other }) => <input type="text" {...input} />;
<Field name="firstName" component={FormGroup} label="Example" content={TextField} />

jason-whitted commented Jul 7, 2016

@erikras I created a repository with an example of the issue.
https://github.com/jason-whitted/redux-form-issue
/src/App.js showcases the issue.

Contributor

jayphelps commented Jul 7, 2016

Just wanted to chime in with a few thoughts..This has been a very non-trivial change for us since we depended heavily on custom components, so now they all require wrappers.

Instead of doing that, we created a helper to do it for us since it was so common.

import { Field } from 'redux-form';
import { pick } from 'lodash';

export const createField = (Component, { pick: pickKeys } = {}) => {
  const Wrapped = ({ input, ...rest }) => {
    let props = { ...input, ...rest };

    if (pickKeys && pickKeys.length) {
      props = pick(props, pickKeys);
    }

    return (
      <Component {...props}>{input.children}</Component>
    );
  };

  return props => ( // eslint-disable-line react/no-multi-comp
    <Field {...props} component={Wrapped}>
      {props.children}
    </Field>
  );
};

You can then use it like so

// Let's assume you have an Autocomplete component
// that accepts these props
Autocomplete.propTypes = {
  onChange: PropTypes.func,
  value: PropTypes.string,
  options: PropTypes.arrayOf(PropTypes.string)
};

// Must do this outside of the render() because
// it must be stable, not changing between renders
const AutocompleteField = createField(Autocomplete);

const Example = () => (
  <div>
    <AutocompleteField
      name="whatever"
      options={['first', 'second', 'third']}
    />
  </div>
);

If you use such a thing, remember that by default you're now providing a bunch of excess props to to the component. If this is an issue, you can pick which ones you want:

const CheckboxField = createField(Checkbox, { pick: ['label', 'onChange', 'value'] });

Using this also means you don't need a separate file to satisfy the eslint rule no-multi-comp (disallowing multiple components per file, which is a good practice but in this case very awkward)

jason-whitted commented Jul 8, 2016

I created a wrapper component that fixes my issue. It can also be used to fix any similar prop issue in the future.

Higher Order Component

/**
 * HOC that remaps properties.
 * @param {function} map - The remap function.  (oldProps) => newProps
 */
const remapProps = map => Component => props => <Component {...map(props)} />;

Example

const remap = ({ input: { label, content, ...input }, ...other }) => 
              ({ label, content, input, ...other });
const RemappedFormGroup = remapProps(remap)(FormGroup);
<Field name="firstName" 
       component={RemappedFormGroup} 
       label="Example" 
       content={TextField} />

The end result is precisely what I was looking for. The label and content props remain at the root of the properties and the input no longer contains them so they will not be passed on erroneously to TextField.

It might be a nice courtesy to include the HOC in redux-form since it has such a small footprint.

The example repository has been updated.

Contributor

gaearon commented Jul 8, 2016

@jason-whitted Looks very similar to mapProps from @acdlite’s recompose. It supports importing an individual module so you might use that instead.

Owner

erikras commented Jul 8, 2016

I guess if you don't want to import mapProps from 'map-props'. 😆 (no really, use @acdlite's)

mapProps is exactly what I was looking for. Not sure how I missed that when combing over the recompose API in the past. Thanks @gaearon and @erikras.

tylergoodman commented Jul 9, 2016

@erikras Regarding #3 in #1249 (comment) , it'd be nice if additional props merged into the root props instead of input.

The big deal with this is that now you can't use defaultProps to automatically shallow-merge your defaults in. Using mapProps is a solution but it's essentially the same as the other props filtering solution.

renderWidget = ({ input: { mySpecialLabel, ...rest } }) =>
//                ^^^^^^^^------ kind of a big deal, if you ask me
  <div>
    <label>{mySpecialLabel}</label>
    <input {...rest}/>
  </div>
// called with
<Field name="whatever" compoenent={renderWidget} mySpecialLabel="Now goes into input"/>

renderWidget.defaultProps = {
  input: {} // oh no
};

In any case I support the idea of an option that decides how props are merged

@neptunian neptunian referenced this issue in jossmac/react-images Jul 10, 2016

Closed

Fix js warnings when using React 15.2 #63

@erikras are you going to port the fixes to v5? If not, what is the recommended react version to be used (anything < 15.2.0)?
Thanks.

suhaotian commented Jul 11, 2016

This change will broken complex form component exist. Please don't do it.
I have a better idea:

// In your component
const {active, dirty, error, invalid, onUpdate, pristine, touched, valid, visited, asyncValidating, autofocus, ...rest} = this.props
// your props in rest
const { el, type, value, onChange, ...other} = rest

just to pipe in with my opinion on the extra props being added to input it does make it hard to validate using flow.

I am using a global redux-form definition that declares InputProps to be:

    declare type InputProps = {
        active: boolean,
        touched: boolean,
        error: ?string,
        input: {
            name: string,
            placeholder?: ?string,
            label?: string,
            value: ?string|number,
            type?: string,
        },
    };

I generally do this to specify the props on my component:

type Props = {
   extra: string,
} & InputProps;

If the extra props get added to input I'd have to override the whole thing rather than just extend it.

Maybe a typescript person could comment about how this would work for them?

The other thing that I'm finding as I update my app to use v6 is that the list of props that I have to destructure out of the input is growing.

This isn't really an issue if you use the props you extract in that file but I have components that I just pass props onto to draw stuff, like errors or labels etc.

So I'm finding that I have to do a lot of // eslint-disable which I find quite uncomfortable as it's a potential source of errors.

tylergoodman commented Jul 12, 2016

@kristian-puccio in Typescript you could do something similar to what you've done in flow

interface InputProps<T> {
    active: boolean;
    touched: boolean;
    error?: string;
    input: {
        name: string;
        placeholder?: string;
        label?: string;
        value?: string | number;
        type?: string;
    } & T
}

interface ComponentProps {
    extra: string;
}

type MyInputComponent = InputProps<ComponentProps>;

var a: MyInputComponent = {
    active: true,
    touched: true,
    input: {
        name: 'a',
        extra: 'stuff',
    },
};

Ok that is nice. Cheers for that!

On 12 July 2016 at 11:58, Tyler Goodman notifications@github.com wrote:

@kristian-puccio https://github.com/kristian-puccio in Typescript you
could do something similar to what you've done in flow

interface InputProps {
active: boolean,
touched: boolean,
error?: string,
input: {
name: string;
placeholder?: string;
label?: string;
value?: string | number;
type?: string,
} & T
}
interface ComponentProps {
extra: string;
}
type MyInputComponent = InputProps;
var a: MyInputComponent = {
active: true,
touched: true,
input: {
name: 'a',
extra: 'stuff',
},
};


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#1249 (comment),
or mute the thread
https://github.com/notifications/unsubscribe/ACA_f7tRWEDzNo3Ggqp78gJswrSXPNoaks5qUvSogaJpZM4JCaoq
.

jvikstedt added a commit to jvikstedt/jnotes_old that referenced this issue Jul 13, 2016

For some reason, using vanilla <input> components I still get the warning after trying the upgrade to 6.0.0-rc.2 (and 3). Also, for those components, it wasn't clear to me how to pass the props.

Here is what my inputs looked like before:

      <form onSubmit={handleSubmit} className={classes.newForm}>

        <div className={classes.row}>
          <div className={classes.formGroup}>
            <input placeholder="First Name"
              type="text" {...firstName}
              className={classes.textInput}/>
          </div>

          <div className={classes.formGroup}>
            <input placeholder="Last Name"
              type="text" {...lastName}
              className={classes.textInput}/>
          </div>
        </div>

          <div className={classes.formGroup}>
            <label>Sex</label>
            <div className={classes.buttonGroup}>
             <label className={classes.defaultButton}>
                <input type="radio" {...sex}
                  value="male" checked={sex.value === 'male'}/> Male
              </label>
             <label className={classes.defaultButton}>
                <input type="radio" {...sex}
                  value="female" checked={sex.value === 'female'}/> Female
              </label>
            </div>
          </div>

    </form>

So the way I interpreted your instructions, I thought I had to modify them like so:

      <form onSubmit={handleSubmit} className={classes.newForm}>

        <div className={classes.row}>
          <div className={classes.formGroup}>
            <input placeholder="First Name"
              type="text" {...firstName.input}
              className={classes.textInput}/>
          </div>

          <div className={classes.formGroup}>
            <input placeholder="Last Name"
              type="text" {...lastName.input}
              className={classes.textInput}/>
          </div>
        </div>

          <div className={classes.formGroup}>
            <label>Sex</label>
            <div className={classes.buttonGroup}>
             <label className={classes.defaultButton}>
                <input type="radio" {...sex.input}
                  value="male" checked={sex.value === 'male'}/> Male
              </label>
             <label className={classes.defaultButton}>
                <input type="radio" {...sex.input}
                  value="female" checked={sex.value === 'female'}/> Female
              </label>
            </div>
          </div>

    </form>

But that throws an error. Something to the effect of 'no property input...'

Thanks!

stephanethomas added a commit to Automattic/delphin that referenced this issue Jul 18, 2016

ericnograles commented Jul 22, 2016

Sorry guys, I arrived super late to this party, but I wanted to bump @jasongonzales23's prior comment. My code is structured the same way as his with 6.0.0-rc3 (swapped out the {...whateverField} destructuring to {...whateverField.input} for a vanilla <input>) but I also got the same RSOD complaining about "no property input".

[Update]: Durr, I'm an idiot, I see the v6 migration guide and using the Field component. For posterity: http://redux-form.com/6.0.0-alpha.15/docs/MigrationGuide.md/

@ericnograles thanks! Somehow I missed the migration guide. Will implement this soon!

MrSkinny commented Jul 23, 2016

Sorry I'm a bit new on this but I followed the migration v6 guide to try to resolve the Unknown properties warning. All warnings are now gone, but my form is behaving super strange -- basically, I can manually focus an input element, type one character and then it suddenly loses focus! I re-focus the input using the mouse and can type normally. When I tab to next field, the same de-focus happens. But after the second time of manually re-focusing the input, this never happens again and I can type and tab between fields as normal. 100% replicable. This is my component:

import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';
import { createPost } from '../actions';

const renderFormcontrol = function (props, controlType) {
  const CustomTag = `${controlType}`;
  console.log(props);

  return(
    <div>
      <CustomTag {...props.input} />
      {props.touched &&
        props.error &&
      <span className="error">{props.error}</span>}
    </div>
  );
};

class PostsNew extends Component {
  render () {
    const { handleSubmit } = this.props;

    return(
      <div className="container">
        <form onSubmit={handleSubmit(props => createPost(props))}>
          <h3>Create Post</h3>
          <div className="form-group">
            <label>Title</label>
            <Field type="text" className="form-control" component={props => renderFormcontrol(props, 'input')} name="title" />
          </div>
          <div className="form-group">
            <label>Categories</label>
            <Field type="text" className="form-control" component={props => renderFormcontrol(props, 'input')} name="categories" />
          </div>
          <div className="form-group">
            <label>Content</label>
            <Field className="form-control" component={props => renderFormcontrol(props, 'textarea')} name="content" />
          </div>

          <button type="submit" className="btn btn-primary">Submit</button>
        </form>
      </div>
    );
  }
}

export default reduxForm(
  {
    form: 'PostsNew'
  },
  null,
  { createPost }
)(PostsNew);

OK, I've confirmed it's happening because instead of using a renderInput function, I was allowing a dynamic element name to be passed so you could use the same function for rendering a textarea.

The redux-form v6 looks great but I'm still with problems using third-party inputs. The following code throws the warning:
bundle.js?v=1:9310 Warning: Unknown props defaultCountry, active, asyncValidating, dirty, error, invalid, input, pristine, touched, valid, visited, autoFormat, onlyCountries, excludeCountries, isValid, flagsImagePath, onEnterKeyPress on tag. Remove these props from the element.

<Field name="phone" component={props => ( <ReactPhoneInput defaultCountry={'br'} {...props} required/> )} />

I know some of the wrong properties come from the ReactPhoneInput but others are still from redux-form.

elyobo commented Jul 26, 2016

@erikras, as @oliverchoy asked, is there any plan to fix this in v5? As v6 is not yet out it would be nice to have a v5 fix.

Contributor

Strato commented Jul 28, 2016

v5 fix expected here too...

@tbash tbash referenced this issue in facebookincubator/create-react-app Aug 2, 2016

Closed

redux-form and create-react-app not working #325

+1 for fixing this in v5. #1444 shows why v5 is preferred over v6 currently

Would love to have a v5 fix as well. Migrating to v6 isn't really feasible for the reason stated in #1444.

elyobo commented Aug 10, 2016

Re: v5 props, @erikras has mentioned a workaround elsewhere, copied below. It'll silence the noise anyway.

const domOnlyProps = ({
  initialValue,
  autofill,
  onUpdate,
  valid,
  invalid,
  dirty,
  pristine,
  active,
  touched,
  visited,
  autofilled,
  ...domProps }) => domProps

SOSANA commented Aug 11, 2016

for v5 will the doc's be updated to reflect handling this issue? anyone have a v5 example to share of using this function to pass in our fields object?

The workaround worked out perfectly. Thank you @elyobo for posting on this thread.

elyobo commented Aug 11, 2016

@SOSANA it just picks out the extra fields that have meaning to redux-form and returns the rest, so you can just spread the result, e.g.

const { fields: { myfield } } = this.props;
return <input {...domOnlyProps(myfield)} />;

instead of

const { fields: { myfield } } = this.props;
return <input {...myfield} />;

SOSANA commented Aug 11, 2016

@elyobo thanks for quick reply! worked as expected

@gnujoow gnujoow referenced this issue in pjhjohn/jsonplaceholder-client Aug 18, 2016

Closed

form validation #26

yourfavorite commented Aug 23, 2016

@elyobo Thanks for sharing the fix on this. The warning is gone in console now, but eslint is throwing errors due to no-unused-vars on each of the properties within domOnlyProps. Any suggestions for fixing this aside from disabling no-unused-vars for the file?

elyobo commented Aug 23, 2016

@yourfavorite I disable that warning for this function; the unused vars are deliberate in this case, using destructuring to pick out the props that redux form cares about so that we can pass back everything else.

My version looks like this -

/* eslint-disable no-unused-vars */                                             
// TODO: remove once upgraded to redux-form v6, which makes this redundant      
export const domOnlyProps = ({                                                  
  initialValue,                                                                 
  autofill,                                                                     
  onUpdate,                                                                     
  valid,                                                                        
  invalid,                                                                      
  dirty,                                                                        
  pristine,                                                                     
  active,                                                                       
  touched,                                                                      
  visited,                                                                      
  autofilled,                                                                   
  error,                                                                        
  ...domProps,                                                                  
}) => domProps;                                                                 
/* eslint-enable no-unused-vars */                                              

Herbertvc added a commit to Herbertvc/React_101 that referenced this issue Aug 24, 2016

@pjhjohn pjhjohn referenced this issue in pjhjohn/jsonplaceholder-client Aug 27, 2016

Closed

Entering /posts/new causes warning #35

Quite dumb proposal, but alternatively data- prefix could be used for such 3rd-party props. Yes, they will end up in DOM, but it might be even benefit in some cases.

Async validation documentation this documentation is not updated with the v6 way of doing things (props under input, meta)

Collaborator

gustavohenke commented Mar 3, 2017

@glcheetham, you're looking at a way too old version of the docs! A lot of stuff changed since v6.0.0-rc.1.
http://redux-form.com/6.5.0/examples/asyncValidation/

gabrielpoca added a commit to gabrielpoca/meteor-redux-demo that referenced this issue Mar 29, 2017

Fix unknown properties warning
This change solves issue
#3 that's caused
by erikras/redux-form#1249 .
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment