React组件通信

父组件向子组件传值

props

//parent
export const Parent = () => {
  return <Children name="name" />
}
//children
export const Children = ({name}) => {
  return <div>{name}</div>
}

子组件向父组件传值

props和函数回调

//parent
export const Parent = () => {
  return <Children getName={(name)=>{
    console.log(name);
  }} />
}
//children
export const Children = ({getName}) => {
  return <button onClick={getName("name")}>按钮</button>
}

多层嵌套组件传值

  • 面对多层嵌套组件,我们仍然可以通过使用props一层一层的传递,但是这样维护起来更加的麻烦,而且有的props的值可能不是中间组件所需要的。

  • 使用context来实现多层嵌套组件传值。

  • 当然你也可以使用redux来实现。

这里说明一下context的实现方法。

//App.js
import Children from "./components/Children";
import { createContext, useState } from "react";
export const Context = createContext();
function App() {
  const [num, setNum] = useState(1);
  return (
    <Context.Provider value={{num, setNum}}>
      parentComponent:{num}
      <Children />
    </Context.Provider>
  );
}
export default App;
//children.js
import React, { useContext } from 'react'
import { Context } from '../../App';
import GrandSon from '../grandSon'

export default function Children() {
  const {num, setNum} = useContext(Context);
  return (
    <>
      childrenComponent:{num}
      <GrandSon />
    </>
  )
}
//grandSon.js
import React, { useContext } from 'react'
import { Context } from '../../App';

export default function GrandSon() {
  const {num, setNum} = useContext(Context);
  return (
    <div>grandSonComponent:{num}</div>
  )
}

兄弟组件传值

state提升可以找到兄弟组件的公共的父组件,将状态提升到父组件。

不相关组件传值

  • 给全局加上context

  • 使用redux来进行全局状态管理

  • 可以使用自定义事件通信(发布订阅模式)

这里说一下自定义事件通信。需要使用一个events来实现。

npm install events --save

创建一个ev.js文件

//ev.js
import { EventEmitter } from "events"; 
export default new EventEmitter();
//App.js
import Children from "./components/Children";
import Children2 from "./components/Children2";
function App() {
  return (
    <div>
      <Children />
      <Children2 />
    </div>
  );
}
export default App;
//children.js
import React, { useEffect } from 'react'
import emitter from '../../ev';
export default function Children() {
  useEffect(() => {
    emitter.addListener('sendMsg', (msg) => {
      console.log("children receive message:",msg);
    })
  }, [])
  return (
    <div></div>
  )
}
//children2.js
import React from 'react'
import emitter from '../../ev'
export default function Children2() {
  return (
    <>
      <button onClick={() => {
        emitter.emit('sendMsg', 'children2 to children send message');
      }}>点击</button>
    </>
  )
}