How to properly bind Chang callback to 'this' using ReactJS, Redux and ES2015?

I am studying ReactJS and Redux, and I cannot figure out how to access my TextField instance when binding it to a Change call on this .

(I use material-ui for this example, but without it I would run into the same problem)

 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); 

I am using a solution that I find ugly (not reusable => not very "component friendly") by setting the id on my TextField and getting its value with document.getElementById('myField').value

How could I get rid of this id and access it with something like textFieldRef.value inside my callback?

I tried without .bind(this) , which gives me access to my TextField instance through this , but I can no longer access my this.props.setDataValue() function since this not bound to my class context.

Thanks!

+5
source share
2 answers

Avoid using calls such as document.getElementById in the React component. React has already been developed to optimize costly DOM calls, so you work with frameworks to do this. If you want to know how DOM nodes are referenced in React, read the docs here .

However, in this situation, you really don't need links. Placing ref (or ID) on a TextField will not necessarily work. What you are referencing is a React element, not a DOM node.

Instead, use the onChange callback onChange . The function passed to onChange is called with the argument event . You can use this argument to get the input value. (see React Event System .)

Your event handler should look like this:

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

And your TextField should look like this:

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

Note: Use the value NOT defaultValue .

+15
source

Using state with Redux is a bad style. So this is a code design problem.

Redux was to be used with functional components, not classes.

I suggest using a functional component and passing the syntax event as a parameter to the onChange function as follows:

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

and then use something like this inside the element:

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

You can also pass your own properties to elements:

 const mapDispatchToProps = (dispatch) => { 
+3
source

Source: https://habr.com/ru/post/1241561/


All Articles