React父子通信,即父组件将一个函数作为子组件的props传给子组件,子组件在恰当时候调用
如果是爷孙通信,则爷爷组件要先传给父组件,父组件再传给子组件,以此类推
**

示例1:龟兔赛跑

http://js.jirengu.com/dupajiduvi/4/edit?html,js,output
将函数组件改为class组件,通过inline style让兔子动起来

  1. class Track1 extends React.Component {
  2. constructor(){
  3. super()
  4. let n = 0
  5. this.state = {
  6. style: {
  7. transform: `translate(${n}%)` // 这里是对象,属性值要加引号
  8. }
  9. }
  10. let intervalID = setInterval(()=>{
  11. n += 10
  12. this.setState({
  13. style: {
  14. transform: `translate(${n}%)`
  15. }
  16. })
  17. if (n >= 100) {
  18. clearInterval(intervalID)
  19. }
  20. },1000)
  21. }
  22. render(){
  23. return (
  24. <div>
  25. <div style={this.state.style}>🐇</div>
  26. <div className='track'></div>
  27. </div>
  28. )
  29. }
  30. }

给组件传一个回调函数,当兔子跑完时,显示信息

  1. function App(){
  2. let success = (x)=>{
  3. console.log(`我是${x},我到终点了`)
  4. }
  5. return (
  6. <div>
  7. <div className="header">
  8. <Time1 />
  9. <Referee />
  10. <Time2 />
  11. </div>
  12. <Track1 success={success}/>
  13. <Track2 success={success}/>
  14. </div>
  15. )
  16. }
  17. class Track1 extends React.Component {
  18. // ...
  19. if (n >= 100) {
  20. clearInterval(intervalID)
  21. this.props.success('兔子') // 调用
  22. }
  23. },1000)
  24. }
  25. // ...
  26. }

要记录时间,并传给Timer组件,用函数组件行不通,改用class

  1. class App extends React.Component {
  2. constructor(){
  3. super()
  4. this.state = {
  5. result1: 0,
  6. result2: 0,
  7. }
  8. this.t0 = new Date()
  9. }
  10. success(x) {
  11. console.log(`我是${x},我到终点了`)
  12. if(x==='兔子'){
  13. this.setState({
  14. result1: new Date() - this.t0
  15. })
  16. } else if (x === '乌龟'){
  17. this.setState({
  18. result2: new Date() - this.t0
  19. })
  20. }
  21. }
  22. render(){
  23. return (
  24. <div>
  25. <div className="header">
  26. <Time1 time={this.state.result1}/>
  27. <Time2 time={this.state.result2}/>
  28. </div>
  29. <Track1 success={this.success.bind(this)}/>
  30. <Track2 success={this.success.bind(this)}/>
  31. </div>
  32. )
  33. }
  34. }
  35. function Time1(props){
  36. return (
  37. <div>
  38. <h3>🐇用时</h3>
  39. <div>{props.time}</div>
  40. </div>
  41. )
  42. }

在Track1和Track2组件外再加一层,变成爷孙组件

  1. class App extends React.Component {
  2. // ...
  3. render(){
  4. return (
  5. <div>
  6. <div className="header">
  7. <Time1 time={this.state.result1}/>
  8. <Time2 time={this.state.result2}/>
  9. </div>
  10. <Playground success={this.success.bind(this)}/>
  11. </div>
  12. )
  13. }
  14. }
  15. function Playground(props){
  16. return (
  17. <div>
  18. <Track1 success={props.success}/>
  19. <Track2 success={props.success}/>
  20. </div>
  21. )
  22. }
  23. // ...

示例2:子组件修改父组件数据

调用父组件的函数进行修改
http://js.jirengu.com/ximocaqeki/1/edit?html,js,output

  1. class App extends React.Component {
  2. constructor(){
  3. super()
  4. this.state = {
  5. message: "hello"
  6. }
  7. }
  8. changeMsg(x) {
  9. this.setState({
  10. message: x
  11. })
  12. }
  13. render(){
  14. return (
  15. <div>
  16. <Child message={this.state.message} fn={this.changeMsg.bind(this)}/>
  17. </div>
  18. )
  19. }
  20. }
  21. function Child(props){
  22. return (
  23. <div>
  24. <p>我得到的信息是 {props.message}</p>
  25. <button onClick={()=>props.fn('ahahahahaha')}>click</button>
  26. </div>
  27. )
  28. }
  29. ReactDOM.render(<App />, document.querySelector("#root"))