Lifting up the State (callbacks)
info
How do you update data in a parent component from a child component? Use a callback
Parent Component
Class Component | Function Component |
---|---|
AppType export class AppType extends React.Component { constructor(props) { super(props); this.state = { localClickCount: 0, sharedClickCount: 0 } this.localClickHandler = () => { console.log( "L[" + this.state.localClickCount + "]" ); this.setState( {localClickCount: this.state.localClickCount + 1} ); } this.sharedClickHandler = () => { console.log( "S[" + this.state.clickCount + "]" ); this.setState( {sharedClickCount: this.state.sharedClickCount + 1} ); } } render(){ return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> Application says: {this.state.localClickCount} </p> <button onClick={() => { this.localClickHandler() } }>Click me </button> <p>React App says: {this.state.sharedClickCount}</p> <SimpleCounter handleClick={this.sharedClickHandler}/> </header> </div> ); } } | App const App = () => { const [sharedClickCount, setSharedCount] = useState(0); const [localClickCount, setLocalCount] = useState(0); let sharedClickHandler = () => { console.log( "S[" + sharedClickCount + "]" ); setSharedCount( sharedClickCount + 1 ); } let localClickHandler = () => { console.log( "L[" + localClickCount + "]" ); setLocalCount( localClickCount + 1 ); } return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> Application says: {localClickCount} </p> <button onClick={() => { localClickHandler() } }>Click me </button> <p>React App says: {sharedClickCount}</p> <SimpleCounter handleClick={sharedClickHandler}/> </header> </div> ); } |
SimpleCounter Component
SimpleCounter
function SimpleCounter(props) { // Declare a new state variable, which we'll call "count" const [count, setCount] = useState(0); let updateParent = async function(){ props.handleClick(); } return ( <div> <button onClick={() => { if( props.handleClick != null ) { updateParent(); //props.handleClick(); } setCount(count + 1); } }>Click me </button> <p>Simple Counter says: {count} times</p> </div> ); }
Complete file listing
App.jsx
import React, {useState} from 'react'; import logo from './logo.svg'; import './App.css'; function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } function SimpleCounter(props) { // Declare a new state variable, which we'll call "count" const [count, setCount] = useState(0); let updateParent = async function(){ props.handleClick(); //await sleep(1000); } return ( <div> <button onClick={() => { if( props.handleClick != null ) { updateParent(); //props.handleClick(); } setCount(count + 1); } }>Click me </button> <p>Simple Counter says: {count} times</p> </div> ); } export class AppType extends React.Component { constructor(props) { super(props); this.state = { localClickCount: 0, sharedClickCount: 0 } this.localClickHandler = () => { console.log( "L[" + this.state.localClickCount + "]" ); this.setState( {localClickCount: this.state.localClickCount + 1} ); } this.sharedClickHandler = () => { console.log( "S[" + this.state.clickCount + "]" ); this.setState( {sharedClickCount: this.state.sharedClickCount + 1} ); } } render(){ return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> Application says: {this.state.localClickCount} </p> <button onClick={() => { this.localClickHandler() } }>Click me </button> <p>React App says: {this.state.sharedClickCount}</p> <SimpleCounter handleClick={this.sharedClickHandler}/> </header> </div> ); } } const App = () => { const [sharedClickCount, setSharedCount] = useState(0); const [localClickCount, setLocalCount] = useState(0); let sharedClickHandler = () => { console.log( "S[" + sharedClickCount + "]" ); setSharedCount( sharedClickCount + 1 ); } let localClickHandler = () => { console.log( "L[" + localClickCount + "]" ); setLocalCount( localClickCount + 1 ); } return ( <div className="App"> <header className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <p> Application says: {localClickCount} </p> <button onClick={() => { localClickHandler() } }>Click me </button> <p>React App says: {sharedClickCount}</p> <SimpleCounter handleClick={sharedClickHandler}/> </header> </div> ); } export default App;