Help us understand the problem. What is going on with this article?

React.jsで"Unknown prop"に立ち向かう

More than 3 years have passed since last update.

はじめに

React.jsを使っていて、こんなことを言われたことはないだろうか

Warning: Unknown prop `webkitdirectory` on <input> tag. Remove this prop from the element. For details, see https://fb.me/react-unknown-prop

Chromeでしか使えないプロパティにつく接頭辞"webkit"ではあるが、使えてほしい。

tl;dr

render()では該当するattributeを書かず、componentDidMountで追加すれば良い

ISSUEを確認してみる

ISSUE#3468: JSX render won't allow webkitdirectory and directory to be used

まさにこれ

とりあえずwhitelistに書かれたプロパティしか認めてないから、それ以外はunkonws propらしい
多くのcomponentが子要素にプロパティを渡しすぎているから、ISSUE#140にあるけどしばらく修正不可らしい

でも、ISSUE#3468の中に、解決された、と参照されているPRがある。

PR#3644: Add webkitdirectory and nwdirectory attributes for input file

Merged!?とおもいきや一番下でReverted...

理由は

  • たとえ本来のプロパティ名がキャメルケースでなくても、reactでは全てキャメルケースにしている
  • まだ標準ではないし、むやみにサポートするべきでもない

とのこと

う〜んわかるけど使いたい!!!

解決策

render()では該当するattributeを書かず、componentDidMountで追加すれば良い

"use strict";

import React from 'react';
import ReactDOM from 'react-dom';

export default class FileInput extends React.Component {
    componentDidMount() {
        let node = this._input;
        node.webkitdirectory = true;
        node.directory = true;
    }
    render() {
        return (
            <input type="file" ref={(c) => {this._input = c;}} {...this.props} />
        );
    }
}

闇の方法だけど成功😇

おまけ

ボタンを装飾する

スクリーンショット 2016-09-01 14.11.19.png

コードは以下

"use strict";

import React from 'react';
import ReactDOM from 'react-dom';

export default class FileInput extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            hover: false
        };
    }
    componentDidMount() {
        let node = ReactDOM.findDOMNode(this.refs.filesInput)
        node.webkitdirectory = true;
        node.directory = true;
    }
    onMouseEnter() {
        this.setState({hover: true});
    }

    onMouseLeave() {
        this.setState({hover: false});
    }
    render() {
        let labelStyle = {
            color: "brown",
            backgroundColor: "transparent",
            border: "solid 2px brown",
            boxSizing: "border-box",
            padding: 20,
            borderRadius: 12
        }
        let hoverLabelStyle = {
            color: "white",
            backgroundColor: "brown",
            border: "solid 2px brown",
            boxSizing: "border-box",
            padding: 20,
            borderRadius: 12
        }
        return (
            <label htmlFor="file-input" style={this.state.hover ? hoverLabelStyle : labelStyle} onMouseEnter={this.onMouseEnter.bind(this)} onMouseLeave={this.onMouseLeave.bind(this)}>
                +フォルダを選択
                <input type="file" id="file-input" ref="filesInput" style={{display: "none"}} {...this.props} />
            </label>
        );
    }
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした