l-emi l-emi - 1 month ago 15
Javascript Question

React not updating text (issue with .getDOMNode())

I'm using React to make a Markdown previewer and trying to make sense of what was used here to make the right box update with a live preview as soon as the text is changed on the left. They have this code at the bottom:

var RawInput = React.createClass({
update:function(){
var modifiedValue=this.refs.inputValue.getDOMNode().value;
this.props.updateValue(modifiedValue);
},
render:function(){
return (<textarea rows="22" type="text" ref="inputValue" value={this.props.value} onChange={this.update} className="form-control" />)
}
});


I implementing this in my code:

const InputText = React.createClass ({
update() {
let newValue = this.refs.inputValue.getDOMNode().value;
this.props.updateValue(newValue);
},
render() {
return (
<div>
<textarea
id="input-text"
rows="18"
type="text"
ref="inputValue"
value={this.props.value}
onChange={this.update}
/>
</div>
);
}
});


The app runs fine except that there is no live preview and the text on the right doesn't update. In the console I get this error:
this.refs.inputValue.getDOMNode is not a function
.

Here is the full code:

import React from 'react';
import Banner from './components/Banner.jsx';
import ContainerHeader from './components/ContainerHeader.jsx';
import marked from 'marked';

const App = React.createClass ({
updateValue(newValue) {
this.setState ({
value: newValue
})
},
getInitialState() {
return {
value: 'Heading\n=======\n\nSub-heading\n-----------\n \n### Another deeper heading\n \nParagraphs are separated\nby a blank line.\n\nLeave 2 spaces at the end of a line to do a \nline break\n\nText attributes *italic*, **bold**, \n`monospace`, ~~strikethrough~~ .\n\nShopping list:\n\n * apples\n * oranges\n * pears\n\nNumbered list:\n\n 1. apples\n 2. oranges\n 3. pears\n'
}
},
markup(value) {
return {__html: value}
},
render() {
return (
<div>
<Banner />
<div className="container">
<div className="row">
<div className="col-xs-12 col-sm-6">
<ContainerHeader text="I N P U T" />
<InputText
value={this.state.value}
updateValue={this.updateValue} />
</div>
<div className="col-xs-12 col-sm-6">
<ContainerHeader text="O U T P U T" />
<div id="output-text">
<span dangerouslySetInnerHTML={this.markup(marked(this.state.value))}></span>
</div>
</div>
</div>
</div>
</div>
);
}
});

const InputText = React.createClass ({
update() {
let newValue = this.refs.inputValue.getDOMNode().value;
this.props.updateValue(newValue);
},
render() {
return (
<div>
<textarea
id="input-text"
rows="18"
type="text"
ref="inputValue"
value={this.props.value}
onChange={this.update}
/>
</div>
);
}
});

export default App;


Any help welcome on solving this, and thanks!

Answer

Since version 15.* in React this.refs.inputValue refers to DOMElement, so you don't need use getDOMNode;

this.refs.inputValue.value

However, I think in this case you don't need use refs, as you call update inside onChange event, you can get target(refer to textarea) from event object, and from target get value

update(e) {
  this.props.updateValue(e.target.value);
},