Reputation: 3407
I am following a tutorial to understand how React.js
works. I am stuck where using refs to access components. If anyone don't mind help look at my code and tell me where I am wrong. But, this is what I did. I have a general component App
and html Input
tag that update the refs
in the State
. But, I don't know why it's still showing undefined
import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
constructor() {
super();
this.state = {
red: 0,
green: 0,
blue: 0
}
this.update = this.update.bind(this);
}
//To manage the state
update(e) {
this.setState({
red: ReactDOM.findDOMNode(this.refs.red.refs.inp).value,
green: ReactDOM.findDOMNode(this.refs.green.refs.inp).value,
blue: ReactDOM.findDOMNode(this.refs.blue.refs.inp).value
})
console.log(this.state); //<This is giving me Object {red: undefined, green: undefined, blue: undefined}
}
render() {
return (
<div>
<Slider ref="red" update={this.update}/>
{console.log(this.state.red)} // This is undefined
{this.state.red}
<br />
<Slider ref="green" update={this.update}/>
{console.log(this.state.green)} // This is undefined
{this.state.green}
<br />
<Slider ref="blue" update={this.update}/>
{console.log(this.state.blue)} // This is undefined
{this.state.blue}
<br />
</div>
)
}
}
//Working with refs. Refs are a way of referencing components within our react application
class Slider extends React.Component {
render() {
return (
<div>
<input ref="inp" type="range" min="0" max ="255" onChange={this.props.update}/>
</div>
)
}
}
ReactDOM.render(
<App />, document.getElementById('app')
);
export default App;
Upvotes: 1
Views: 1460
Reputation: 3056
According to React doc :
If you have not programmed several apps with React, your first inclination is usually going to be to try to use refs to "make things happen" in your app. If this is the case, take a moment and think more critically about where state should be owned in the component hierarchy. Often, it becomes clear that the proper place to "own" that state is at a higher level in the hierarchy. Placing the state there often eliminates any desire to use refs to "make things happen" – instead, the data flow will usually accomplish your goal.
Try this :
class App extends Component {
constructor(){
super();
this.state = {
slider : 0,
}
this.update = (e) => {
const {name,value} = e.target;
this.setState({
[name] : value,
})
}
}
render() {
return (
<div>
<Slider name="slider" update={this.update} />
{this.state.slider}
</div>
);
}
}
class Slider extends React.Component {
render() {
return (
<div>
<input name={this.props.name} type="range" min="0" max="255" onChange={this.props.update}/>
</div>
)
}
}
Upvotes: 3
Reputation: 128
findDOMNode returns the corresponding native browser DOM element, which is in your case:
<div>
<input type="range" min="0" max ="255" onChange={this.props.update} />
</div>
So you are reading the value of the div instead of the input.
Check this fix http://jsfiddle.net/69r5kn16/2/
Upvotes: 2
Reputation: 1625
if you want to use refs
, you should use them after your component have been mounted, it means you should use them in componentDidMount
.
I see you call this.update
in your Slider
Component. the order componentDidMount
of child component and parentComponent is as follow:
componentWillMount Of parent
componentWillMount of child
componentDidMount of child
componentDidMount of Parent.
please check when do you call update
method in your Slider Component.
Upvotes: 1