JavaScript
reactjs
React
redux
redux-form

React15.2.0でRedux-FormV5ワーニング対策&V6使用例

More than 1 year has passed since last update.

React 15.2.0を使い始めたら・・・!!!

React15.2.0がリリースされました。エラー周りが強くなっててこれはいいぞ!と使っていたところ、redux-formを実装したら、warningが吐き出されるようになっていた。

warningの内容は

bundle.js:1309 Warning: Unknown props initialValue, autofill, onUpdate, valid, invalid, dirty, pristine, active, touched, visited, autofilled on <input> tag. Remove these props from the element. For details, see

よくわかんないpropsを渡さないでくださいよ!

ということらしい。どうやらReact 15.2.0では予期しないprops(属性として設定できない値)を渡すとWarningが出る模様。

redux-formを使う際には

<input type="text" {...this.props.fields.txt} />

このようにスプレッド演算子を使って書くことが多いというか公式のサンプルもそうなっている。すると、this.props.fields.txtには、

{
  active:false,
  autofill:(value),
  autofilled:false,
  checked:undefined,
  dirty:false,
  initialValue:"",
  invalid:false,
  name:"txt",
  onBlur:(event),
  onChange:(event),
  onDragStart:(event),
  onDrop:(event),
  onFocus:(),
  onUpdate:(event),
  pristine:true,
  touched:false,
  valid:true,
  value:"",
  visited:false
}

とたくさんのプロパティが詰め込まれている。
そのため本来はinputで扱えない属性も設定してしまっていることが原因らしい。。。

対策

並行してMaterial-uiも使っていたがそちらでも一部コンポーネントについてはWarningが出ていたため、めんどくさくなり15.1.0に戻したが後日、改めてredux-formでの対策を調べてみた。

 V5で必要ないプロパティを取り除く

import React, {Component} from 'react';
import {render} from 'react-dom';
import { createStore, combineReducers,applyMiddleware } from 'redux'
import { Provider } from 'react-redux';
import { reduxForm, reducer, Field } from 'redux-form';
import createLogger from 'redux-logger';

const logger = createLogger();

let obj = combineReducers({form:reducer});
const store = createStore(obj,applyMiddleware(logger));

class App extends Component{
  render(){
    return (
      <Provider store={store}>
        <Main />
      </Provider>
    );
  }
}

class Mainpre extends Component{
  constructor(props){
    super(props);

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

  }
  render(){
    return (
      <div>
        <input 
          type="text" 
          {..._.pick(this.props.fields.txt, this.InputProps)}
        />
      </div>
    );
  }
}
const Main = reduxForm({
  form:'test',
  fields:['txt']
})(Mainpre);

render(<App />, document.getElementById('content'));

これで警告がでるようなプロパティを除いて渡すこと警告がなくなります。underscore.jsを使ってますが、自作でもいいかもしれません。

V6を使う

redux-formV6でも回避できます。

import React, {Component} from 'react';
import {render} from 'react-dom';
import { createStore, combineReducers,applyMiddleware } from 'redux'
import { Provider } from 'react-redux';
import { reduxForm, reducer, Field } from 'redux-form';
import createLogger from 'redux-logger';

const logger = createLogger();

let obj = combineReducers({form:reducer});
const store = createStore(obj,applyMiddleware(logger));

class App extends Component{
  render(){
    return (
      <Provider store={store}>
        <Main />
      </Provider>
    );
  }
}

class Mainpre extends Component{
  constructor(props){
    super(props);
  }

  render(){
    return (
      <div>
        <Field name="txt" component="input" type="text"/>      
      </div>
    );
  }
}

const Main = reduxForm({
  form:'test',
})(Mainpre);

render(<App />, document.getElementById('content'));

具体的にはreduxForm()()からfieldsプロパティがなくなり、Fieldコンポーネントにname="txt"として指定しています。

また、component="input"として、inputを指定していますが、自分で作ったコンポーネントを使いたい時は

<Field name="txt" component={customComponent} type="text"/>      

このようにして、CustomComponent側では、

const customComponent = props =>(
  <div>
    <input {...props.input}/>    
  </div>
);

として受けます。

ご不明点、間違い、こうした方がいいなどございましたらご指摘頂けますと幸いです。