web-dev-qa-db-ja.com

React-propsを渡すことで入力defaultValueを変更する

この例を考えてみましょう:

var Field = React.createClass({
    render: function () {
        // never renders new value...
        return (
            <div>
                <input type="text" defaultValue={this.props.value || ''} />
            </div>
        );
    }
});

var App = React.createClass({
    getInitialState: function () {
        return {value: 'Hello!'};
    },

    changeTo: function (str) {
        this.setState({value: str});
    },

    render: function () {
        return (
            <div>
                <Field value={this.state.value} />
                <button onClick={this.changeTo.bind(null, 'Whyyyy?')}>Change to "Whyyyy?"</button>
                <button onClick={this.changeTo.bind(null, void 0)}>Change to undefined</button>
            </div>
        );
    }
});

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

ダム入力コンポーネントの支柱としてdefaultValueに値を渡したいです。ただし、再レンダリングすることはありません。

21
Kosmetika

前述の答えとして、defaultValueはフォームの初期ロード時にのみ設定されます。その後、意図は初期のデフォルト値を設定することだけであったため、「自然に」更新されません。

keyFieldコンポーネントのように、ラッパーコンポーネントにAppを渡すことで必要に応じてこれを回避できますが、実際的な状況ではおそらくformコンポーネントである。適切なkeyは、たとえばデータベースに格納されているIDのように、フォームに渡されるリソースの一意の値です。

単純化した場合、フィールドレンダリングでこれを行うことができます。

<div key={this.props.value}>
    <input type="text" defaultValue={this.props.value || ''} />
</div>

より複雑なフォームケースでは、たとえば、onSubmitアクションがAPIに送信されたが同じページに留まった場合、次のようなものが必要なものを取得します。

const Form = ({item, onSubmit}) => {
  return (
    <form onSubmit={onSubmit} key={item.id}>
      <label>
        First Name
        <input type="text" name="firstName" defaultValue={item.firstName} />
      </label>
      <label>
        Last Name
        <input type="text" name="lastName" defaultValue={item.lastName} />
      </label>
      <button>Submit!</button>
    </form>
  )
}

Form.defaultProps = {
  item: {}
}

Form.propTypes = {
  item: PropTypes.object,
  onSubmit: PropTypes.func.isRequired
}

制御されていないフォーム入力を使用する場合、通常、値は送信されるまで気にしません。そのため、defaultValuesを本当に更新する場合にのみ再レンダリングを強制する方が理想的です(すべての変更ではなく、送信後に)個々の入力の)。

同じフォームを編集しているときに、API応答が異なる値で返される可能性がある場合は、IDとタイムスタンプのような組み合わせキーを提供できます。

50
Sia

defaultValueは初期ロードに対してのみ機能します。その後、更新されません。状態を維持する必要がありますフィールドコンポーネント:

var Field = React.createClass({
    //transfer props to state on load
    getInitialState: function () {
        return {value: this.props.value};
    },
    //if the parent component updates the prop, force re-render
    componentWillReceiveProps: function(nextProps) {
         this.setState({value: nextProps.value});
    },
    //re-render when input changes
    _handleChange: function (e){
        this.setState({value: e.target.value});
    },
    render: function () {
        // render based on state
        return (
            <div>
                <input type="text" onChange={this._handleChange} 
                                   value={this.state.value || ''} />
            </div>
        );
    }
});
12
drogon

これは 制御された入力と制御されていない入力 に関係していると確信しています。

<input>は制御されない(value属性を定義しない)場合、値は常に初期化された値に解決されます。この場合 Hello!

この問題を解決するには、value属性を追加して、onChangeの間に設定します。

var Field = React.createClass({
      render: function () {
          // never renders new value...
          return (
              <div>
                  <input type="text" defaultValue={this.props.default || ''} value={this.props.value} />
              </div>
          );
      }
  });

これはプランカーです 変更を示しています。

4
Davin Tryon

私もこの問題に直面しています。私がしたことは、小道具が変更されたときに入力値を手動で更新することでした。これをField反応クラスに追加します。

componentWillReceiveProps(nextProps){
    if(nextProps.value != this.props.value) {
        document.getElementById(<element_id>).value = nextProps.value
    }
}

要素を特定できるように、要素にid属性を追加する必要があります。

0
Kael Vergara

条件付きレンダリングを使用すると、コンポーネントは正しい初期値をロードします。このモジュールのようなもの:

class MenuHeaderInput extends React.Component{
    constructor(props){
        super(props);
        this.handleBlur = this.handleBlur.bind (this);
    }
    handleBlur (e) {
        this.props.menuHeaderUpdate(e.target.value);
    }
    render(){
        if (this.props.menuHeader) {
            return (
                <div className="w3-row w3-margin" onClick = {() => this.props.handleTitleClick (10)}>
                    <div className="w3-third" ><pre></pre></div>
                    <input
                        className = {"w3-third w3-input w3-jumbo " + EDIT_COLOR}                
                        type = "text"
                        defaultValue = {this.props.menuHeader}
                        onBlur = {this.handleBlur}
                    />
                    <div className="w3-third" ><pre></pre></div>                
                </div>
            )
        }
        else {
            return null;
        }
    }
}
0
Kaj Risberg

問題はここにあります:

onClick={this.changeTo.bind(null, 'Whyyyy?')}

なぜnullにバインドするのか興味があります。

ChangeToがこのオブジェクトでsetStateになるように、「this」にバインドする必要があります。

これを試して

<button onClick={this.changeTo.bind(this, 'Whyyyy?')}>Change to "Whyyyy?"</button>
<button onClick={this.changeTo.bind(this, void 0)}>Change to undefined</button>

Javascriptでは、関数が呼び出されると、関数は、記述された場所ではなく、呼び出されたスコープで呼び出されます(直観に反するようです)。記述したコンテキストで呼び出されるようにするには、「。bind(this)」にする必要があります。

バインディングと関数スコープの詳細については、多くのオンラインチュートがあります(他のものよりもはるかに優れています)-これが好きかもしれません: http://ryanmorr.com/understanding-scope-and-context- in-javascript /

また、FirefoxまたはChromeを使用している場合は、React Devツールを使用することをお勧めします。これにより、state.messageが変更されていないことがわかります。 https:// facebook.github.io/react/blog/2015/09/02/new-react-developer-tools.html

0
Frazer Kirkman

条件付きで入力を行い、defaultValueの更新を強制するたびに、入力をアンマウントし、すぐに再度レンダリングする必要があります。

0
Bnaya Zil