【问题标题】:How to properly bind onChange callback to 'this' with ReactJS, Redux, and ES2015?如何使用 ReactJS、Redux 和 ES2015 正确地将 onChange 回调绑定到“this”?
【发布时间】:2016-05-03 18:05:01
【问题描述】:

我正在学习 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.props.setDataValue() 函数,因为this 没有绑定到我的类上下文。

谢谢!

【问题讨论】:

    标签: javascript reactjs bind ecmascript-6 redux


    【解决方案1】:

    避免在 React 组件中使用像 document.getElementById 这样的调用。 React 已经被设计为优化昂贵的 DOM 调用,所以你这样做是在对抗框架。如果你想知道如何在 React 中引用 DOM 节点,请阅读文档here

    但是,在这种情况下,您实际上并不需要引用。在TextField 上放置参考(或ID)不一定会起作用。您引用的是 React 元素,而不是 DOM 节点。

    相反,更好地利用onChange 回调。传递给onChange 的函数使用event 参数调用。您可以使用该参数来获取输入值。 (参见 React 的 event system。)

    您的事件处理程序应如下所示:

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

    你的TextField 应该是这样的:

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

    注意:Use value NOT defaultValue.

    【讨论】:

    • 感谢您的快速回答!就这样,事件,我怎么能错过呢?我非常清楚在 React 中使用 document.getElementById 是一种非常糟糕的做法,但我想不出另一种解决方案,因此我的问题是 :) 我应该更仔细地阅读 material-ui 文档,再次感谢。
    【解决方案2】:

    在 Redux 中使用 state 是一种不好的风格。所以这是代码的设计问题。

    Redux 旨在与功能组件一起使用,而不是与类样式组件一起使用。

    我建议使用功能组件并将合成事件作为参数传递给 onChange 函数,如下所示:

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

    然后在元素内部使用类似这样的东西:

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

    你也可以传递元素自己的属性:

    const mapDispatchToProps = (dispatch) => {
    

    【讨论】:

    • 这条线不正确 Redux was meant to be used along with functional components and not class style ones. 来自 redux 文档 If and when you need to add local state, lifecycle methods, or performance optimizations, you can convert them to classes. - redux.js.org/docs/basics/UsageWithReact.html
    猜你喜欢
    • 2017-07-16
    • 2020-01-26
    • 1970-01-01
    • 2016-12-08
    • 1970-01-01
    • 2012-12-24
    • 2021-07-10
    • 1970-01-01
    • 2020-01-15
    相关资源
    最近更新 更多