React Hooks 指北(三):组件数据通信与useContext

394 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情

安排内容

  • 父亲到儿子数据传递
  • 儿子到父亲数据传递
  • useContext:祖先给后代所有传递数据

父亲给儿子数据传递

father.js 父组件

父组件直接在儿子组件上添加 key=val 传递数据

function StateTest () {
  const [num,setNum] = useState(1)
  let age = 22

  //修改age
  const changeAge = () => {
    age = 220
  }
  return (
    <div>
      <div>num:{num}</div>
      <div>age:{age}</div>
      <div onClick={()=>setNum(num+1)}>修改num</div>
      <div onClick={()=>changeAge()}>修改age</div>
      <div>---------------------</div>
      <Son num={num} age={age}/>
    </div>
  )
}

son.js

儿子组件通过props接收父组件的数据(和vue一样,比vue更简单)

 function Son(props) {
  return <div>
    num:{props.num}
    age:{props.age}
  </div>
}

页面初始效果

看下图,我们发现儿子组件成功接收到父亲元素传递的num和age数据

image.png

点击修改num

由于父组件的num是响应式数据,因此父组件的num数据更新后,试图和子组件的num都会发生改变

image.png

点击修改age

由于age是普通数据,因此父组件的age数据修改后,试图和子组件的age都是没反应的

image.png

儿子传递数据给父亲

father.js

父组件传递函数给子组件

function StateTest () {
  const [name,setName] = useState("father")
  
  //提前定义函数
  const fn = (name) => {
    setName(name)
  }
  return (
    <div>
      <div>name:{name}</div>
      <Son func={fn}/>
    </div>
  )
}

儿子组件通过porps接收函数,在需要的地方触发函数,从而间接的传递自己数据给父亲使用

function Son(props) {
  const [name,setName] = useState("son-name1")
  
  //传递数据给父亲
  useEffect(()=>{
    props.func(name,1)
  },[])
  
  //修改自己的数据name
  const changeFather = () => {
    setName("son-name2")
  }
  return <div onClick={()=>{changeFather()}}>
    son :{name}
  </div>
}

初始页面

father初始加载使用自己的数据name显示father.但是当儿子组件加载完成后,将自己的数据给父亲,父亲将自己数据修改成儿子组件传递的数据son-name1

image.png

点击儿子组件修改name

点击儿子组件修改name,儿子组件的name发生了修改并且试图改变。但是父组件的值未改变。说明儿子传递给父组件的值无法传递响应式。

image.png

useContext

当组件层级大于等于3时,我们认定父亲传递给儿子的方式就十分困难。使用useContext可以实现父元素将自己的数据传递给所有的后代使用

father.js

  1. 导入createContext创建context

  2. 父组件使用创建的context包裹儿子组件

  3. 在创建的context使用value={}传递数据给后代

     //必须导出创建的context.后代需要用这个context使用父组件传递的数据
     export const numContext = createContext()
    
     function StateTest () {
       const [num,setNum] = useState(1)
       return (
         <div>
           <div>father:{num}</div>
           <div onClick={()=>setNum(num+1)}>修改num</div>
           
           <numContext.Provider value={num}>
             <Son1/>
             <Son2/>
           </numContext.Provider>
         </div>
       )
     }
     
    

son.js

import { useContext } from "react"
//1.导入父组件创建的context
import { numContext } from "../father"

export default function Son1() {
  //2.接收父组件传递的数据
  const numFather = useContext(numContext)
  return <div>
    //3.使用父组件的数据
    son1:{numFather} 
  </div>
}

初始页面 我们发现,父亲组件的数据成功传递给后代使用。

image.png

修改父组件数据

当我们修改父组件传递的数据,后代组件的数据也发生了更新。

image.png

总结

以上是React中数据通信中父子传递和useContext的总结。谢谢各位支持。