web-dev-qa-db-ja.com

ReactJS、Redux、ES2015でonChangeコールバックを「this」に適切にバインドするにはどうすればよいですか?

ReactJSとReduxを学んでいますが、onChangeコールバックをthisにバインドしているときに、TextFieldインスタンスにアクセスする方法がわかりません。

(この例では material-ui を使用していますが、これがないとまったく同じ問題が発生します)

_import React, {Component} from 'react';
import { connect } from 'react-redux';
import { setDataValue } from './actions/data';
import TextField from 'material-ui/lib/text-field';
import Paper from 'material-ui/lib/paper';

export class DataInput extends Component {
    constructor(props){
        super(props);
    }

    handleTextChange() {
        this.props.setDataValue(document.getElementById('myField').value);
    }

    render(){
        return (
            <Paper style={{
                width: '300px',
                margin: '10px',
                padding: '10px'
            }}>
                <TextField 
                  id='myField'
                  defaultValue={this.props.data.value}
                  onChange={this.handleTextChange.bind(this)} />
            </Paper>
        );
    }
}

export default connect(
  (state) => ({data: state.data}),
  {setDataValue}
)(DataInput);
_

TextFieldにidを設定し、document.getElementById('myField').valueでその値にアクセスすることで、見苦しい(再利用できない=>あまり 'コンポーネントフレンドリーではない')ソリューションを使用しています。

どうすればこのidを取り除き、コールバック内で_textFieldRef.value_のようなものでアクセスできますか?

.bind(this)なしで試しました。これによりthisを介してTextFieldインスタンスにアクセスできますが、thisがないため、this.props.setDataValue()関数にアクセスできなくなりました。クラスコンテキストにバインドされていません。

ありがとうございました !

8
Romain Durand

Reactコンポーネント内でdocument.getElementByIdのような呼び出しを使用することは避けてください。Reactはすでに高価なDOM呼び出しを最適化するように設計されているため、フレームワークに対して作業していますこれを行うことで、ReactでDOMノードを参照する方法を知りたい場合は、ドキュメントを読んでください ここ

ただし、この状況では、実際には参照は必要ありません。 TextFieldにref(またはID)を配置しても、必ずしも機能するとは限りません。参照しているのはReact要素であり、DOMノードではありません。

代わりに、onChangeコールバックをより有効に活用してください。 onChangeに渡された関数は、event引数を使用して呼び出されます。その引数を使用して、入力値を取得できます。 (Reactの イベントシステム を参照してください。)

イベントハンドラは次のようになります。

handleTextChange(event) {
    this.props.setDataValue(event.target.value);
}

そして、あなたのTextFieldは次のようになります。

<TextField 
    value={this.props.data.value}
    onChange={event => this.handleTextChange(event)}
/>

注: defaultValueではなく値を使用

19
David L. Walsh

Reduxと一緒に状態を使用するのは悪いスタイルです。したがって、これはコードの設計上の問題です。

Reduxは、クラススタイルのコンポーネントではなく、機能コンポーネントと一緒に使用することを目的としていました。

関数型コンポーネントを使用し、次のように構文イベントをパラメーターとしてonChange関数に渡すことをお勧めします。

const mapDispatchToProps = (dispatch) => {
return {
    onChange: (value) => {
        dispatch(changeAction(value))
    }
}

次に、要素内で次のようなものを使用します。

<input onChange={ (e) => onChange(e.target.value)}

要素に独自のプロパティを渡すこともできます。

const mapDispatchToProps = (dispatch) => {
1
Den Roman