Reputation: 156
I am trying to update the title of a header component by executing an onchange event in my app.js, but cant seem to bind them correctly. So when user types in input it will show the text in the header component.
APP.JS
import React, { Component } from 'react';
import './App.css';
import Header from './Header';
class App extends Component {
constructor(props) {
super(props);
this.state = {name: "Michael"}
}
handleChange(e) {
const name = e.target.value;
this.changeTitle(name);
}
render() {
return (
<div className="App">
<Header changeTitle={this.changeTitle.bind(this)} title={this.state.name}/>
<p className="App-intro">
Type here to change name.
<input type="text" onChange={this.handleChange.bind(this)}/>
</p>
</div>
);
}
}
export default App;
HEADER.JS
import React, { Component } from 'react';
import logo from './logo.svg';
class Header extends Component {
changeTitle(name) {
this.setState({name});
}
render() {
return (
<div>
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React {this.props.name}</h2>
</div>
</div>
);
}
}
export default Header;
Upvotes: 0
Views: 12853
Reputation: 282160
changeTitle function should be defined in the App component and not in the Header component. In fact you can directly call the changeTitle
component instead of calling it from the handleChange
and in the Header component access the prop as this.props.title
and not this.props.name
import React, { Component } from 'react';
import './App.css';
import Header from './Header';
class App extends Component {
constructor(props) {
super(props);
this.state = {name: "Michael"}
}
changeTitle = (e) =>{
this.setState({name: e.target.value});
}
render() {
return (
<div className="App">
<Header title={this.state.name}/>
<p className="App-intro">
Type here to change name.
<input type="text" onChange={this.changeTitle}/>
</p>
</div>
);
}
}
export default App;
And use it in your Header as
import React, { Component } from 'react';
import logo from './logo.svg';
class Header extends Component {
render() {
return (
<div>
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React {this.props.title}</h2>
</div>
</div>
);
}
}
export default Header;
Working snippet:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {name: "Michael"}
}
changeTitle = (e) =>{
this.setState({name: e.target.value});
}
render() {
return (
<div className="App">
<Header title={this.state.name}/>
<p className="App-intro">
Type here to change name.
<input type="text" onChange={this.changeTitle}/>
</p>
</div>
);
}
}
class Header extends React.Component {
render() {
var logo = 'https://processing.org/tutorials/pixels/imgs/tint1.jpg';
return (
<div>
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React {this.props.title}</h2>
</div>
</div>
);
}
}
ReactDOM.render(<App/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>
Upvotes: 5
Reputation: 104529
You don't need to pass the change event to Header component, just pass the data only and do the setState
in App component.
Reason is you are using Header component only to display the header name, so state should be managed by the parent component App.
Check the working snippet:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {name: "Michael"}
}
handleChange(e) {
const name = e.target.value;
this.setState({name}); //do the setState here
}
render() {
return (
<div className="App">
<Header title={this.state.name}/>
<p className="App-intro">
Type here to change name.
<input type="text" onChange={this.handleChange.bind(this)}/>
</p>
</div>
);
}
}
class Header extends React.Component {
render() {
return (
<div>
<div className="App-header">
<img src={''} className="App-logo" alt="logo" />
<h2>Welcome to React {this.props.title}</h2>
</div>
</div>
);
}
}
ReactDOM.render(<App/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'/>
Upvotes: 1