useContext

用于实现跨组件通信

  1. src/context/index.ts
  2. // 用于创建上下文对象
  3. import { createContext } from 'react'
  4. const context = createContext(0)
  5. export default context
  1. import React from 'react'
  2. import context from './context' // 引入
  3. export default function App() {
  4. const [money] = React.useState(8888)
  5. return (
  6. <div>
  7. <h1 >title</h1>
  8. <context.Provider value={money}>
  9. <Father />
  10. </context.Provider>
  11. </div>
  12. );
  13. }
  14. function Father() {
  15. return (
  16. <div><Son /></div>
  17. )
  18. }
  19. function Son() {
  20. return (
  21. <div><Grandson /></div>
  22. )
  23. }
  24. // import {useContext} from 'react'
  25. function Grandson() {
  26. const Money = React.useContext(context) // 写法1
  27. return (
  28. <div>
  29. <p> {Money} </p> {/* 写法1 */}
  30. <p> {React.useContext(context)} </p>
  31. </div>
  32. )
  33. }

useRef

用于实现ref绑定

类组件中的ref绑定

  1. <h1 ref={el=>this.H1=el}>title</h1>

useRef获取元素
  1. import React from 'react'
  2. export default function App() {
  3. const h1Ref: any = React.useRef(null);
  4. console.log(h1Ref) // {current: null}
  5. const change = () => {
  6. console.log(h1Ref) // {current: h1}
  7. h1Ref.current.style.color = 'red'
  8. }
  9. return (
  10. <div>
  11. <h1 ref={h1Ref}>title</h1>
  12. <button onClick={change}>onClick here change title color</button>
  13. </div>
  14. );
  15. }

useRef获取类组件
  • 案例:在App组件中修改Hello组件的state

操作和useRef获取元素相同

  1. import React from 'react'
  2. export default function App() {
  3. const ChildRef:any=React.useRef(null)
  4. const change=()=>{
  5. // 通过ref绑定获取Child组件的setFn方法
  6. console.log(ChildRef)
  7. // {current: Child {props: {…}, context: {…}, refs: {…}, updater: {…}, setFn: ƒ, …}}
  8. ChildRef.current.setFn()
  9. }
  10. return (
  11. <div>
  12. <button onClick={change}> click </button>
  13. <Child ref={ChildRef}/>
  14. </div>
  15. );
  16. }
  17. interface P {
  18. }
  19. interface S {
  20. Componentname: string
  21. }
  22. class Child extends React.Component<P, S> {
  23. constructor(props: P) {
  24. super(props)
  25. this.state = {
  26. Componentname: 'Child'
  27. }
  28. }
  29. setFn = () => {
  30. this.setState({
  31. Componentname: this.state.Componentname + '.'
  32. })
  33. }
  34. render() {
  35. return (
  36. <div>
  37. <p>{this.state.Componentname}</p>
  38. </div>
  39. )
  40. }
  41. }

useRef获取类组件

ref不能绑定函数组件,但是可以绑定类组件。React提供了React.forwardRef() ,用于解决此问题,该函数调用后返回一个类组件
React.forwardRef 会创建一个React组件,这个组件能够将其接受的 ref 属性转发到其组件树下的另一个组件中。
React.forwardRef 接受渲染函数作为参数。React 将使用 props 和 ref 作为参数来调用此函数。此函数应返回 React 节点。

  1. // Child组件定义:
  2. import React,{forwardRef} from 'react'
  3. function Child() {
  4. const Fn = () => {
  5. console.log(1)
  6. }
  7. return (
  8. <div>
  9. Child
  10. </div>
  11. )
  12. }
  13. export default forwardRef(Child)
  14. //App组件定义
  15. import React from 'react'
  16. import Child from './components/Child'
  17. export default function App() {
  18. const ChildRef: any = React.useRef(null)
  19. const change = () => {
  20. console.log(ChildRef) // {current: null}
  21. }
  22. return (
  23. <div>
  24. <button onClick={change}> click </button>
  25. <Child ref={ChildRef} />
  26. </div>
  27. );
  28. }

此时触发App组件中button的事件打印current为null得知,上述代码已经实现ref不能绑定函数组件的问题,但是并没有访问到Child组件,我们需要使用Hook useImperativeHandle

useImperativeHandle

  1. // 在Chile组件中添加如下代码
  2. function Child(props: any, ref: any) {
  3. React.useImperativeHandle(ref, () => {
  4. return {
  5. Fn
  6. // 需要传什么,也可以是状态title
  7. // return带返回值就是ref获得到到内容
  8. }
  9. })
  10. ......
  11. }
  12. export default forwardRef(Child)

此时上述说的 ChileRef = { current: {Fn: ƒ} }

useReducer

用于定义状态,修改状态,与useState相似

案例:制作一个简易的状态管理 类似vuex