Four ways of communication between react hook components

preface

Since the official introduction of hook by react, many partners have changed from the old class component to hook component. However, there are still some differences between hook component and class component, so the following summarizes four parameter transmission methods

1, Father to son

The child component receives the data from the parent component through props

1. Parent component
import React, { useState } from 'react'

import ChildrenCom from './child'

// Parent component
const ParentCom = () => {
  const [name] = useState('A.Liang')

  return (
    <div>
      <h2>Parent component</h2>
      <ChildrenCom name={name} />
    </div>
  )
}

export default ParentCom
2. Subcomponents
import React, { useState } from 'react'

import ChildrenCom from './child'

// Parent component
import React, { useEffect } from 'react'

// Subcomponents
const ChildrenCom = props => {
  const { name } = props

  useEffect(() => {
    console.log('props==>', props)
  })

  return (
    <div>
      <h4>Subcomponents: </h4>
      <p>Passed from parent to child component name: {name}</p>
    </div>
  )
}

export default ChildrenCom

2, Son to father

The parent component props passes the callback function to the child component

If the child component wants to pass some values to the parent component, or the child component wants to execute a certain section of logic in the parent component after executing a certain section of logic, you can write the corresponding logic function in the parent component and pass this function to the child component through props

1. Parent component
import React, { useState } from 'react'

import Child from './child'
// Parent component
const ParentCom = () => {
  const [count, setCount] = useState(0)

  // Get the value value passed from the sub component and set it to count. The val parameter is the value value of the sub component
  const getChildrenValue = val => {
    setCount(val)
  }

  return (
    <div>
      <h2>Parent component</h2>
      <p>Get the value passed from the sub component:{count}</p>
      {/* Here is the important code. Pass the prop of getValue to the sub component, and its value is a callback function */}
      <Child getValue={getChildrenValue} />
    </div>
  )
}

export default ParentCom
2. Subcomponents
import React, { useState } from 'react'

// Subcomponents
const ChildrenCom = props => {
  const [value, setValue] = useState(0)

  const addValue = () => {
    setValue(value + 1)
    // Pass the value of each increment to the parent component
    props.getValue(value + 1)
  }

  return (
    <div>
      <h4>Subcomponents</h4>
      <button onClick={addValue}>Click to change the of the subcomponent value Value:{value}</button>
    </div>
  )
}

export default ChildrenCom

3, Paternal offspring

Using useContext to realize cross component value transfer

const value = useContext(MyContext);

useContext receives a context object (the return value of React.createContext) and returns the current value of the context. The current context value is determined by < mycontext. Com, which is closest to the current component in the upper component The value of provider > is determined by prop.

1,context.js
import { createContext } from 'react'

const myContext = createContext(null)

export default myContext
2. Parent component
import React, { useReducer } from 'react'

import myContext from './createContext'
import Child from './child'

const reducer = (state, action) => {
  const [type, payload] = action
  switch (type) {
    case 'set':
      return {
        ...state,
        ...payload,
      }
    default:
      return {
        ...state,
        ...payload,
      }
  }
}

const initData = {
  name: 'A.Liang',
}

const ParentCom = () => {
  const [state, dispatch] = useReducer(reducer, initData)

  return (
    <div style={{ backgroundColor: '#f2f2f2' }}>
      <h1>Test Topmost component----Realize cross component value transfer.</h1>
      <button
        onClick={() => {
          dispatch(['set', { name: 'The parent component changed its name' }])
        }}
      >
        Click me to modify name
      </button>
      <br />
      Parent component-name: {state.name}
      <hr />
      <myContext.Provider
        value={{
          name: state.name,
          // Pass the dispatch of the topmost Test component to the descendant component, so that the descendant component can modify the data of the topmost component.
          proDispatch: dispatch,
        }}
      >
        {/* Subcomponents */}
        <Child />
      </myContext.Provider>
    </div>
  )
}

export default ParentCom
3. Subcomponents
import React, { useContext } from 'react'

import myContext from './createContext'
import ChildChild from './child-child'

// Subcomponents
const ChildrenCom = () => {
  const { name, proDispatch } = useContext(myContext)

  function changeName() {
    proDispatch([
      'set',
      {
        name: 'Subcomponent changed name',
      },
    ])
  }

  return (
    <div>
      <h4>Subcomponents: </h4>
      <button onClick={changeName}>A child component modifies the of the parent component name</button>
      <p>Passed from parent to child component name: {name}</p>
      <ChildChild />
      <hr />
    </div>
  )
}

export default ChildrenCom
4. Descendant component
import React, { useContext } from 'react'

import myContext from './createContext'

// Descendant component
const ChildrenCom = () => {
  const { name, proDispatch } = useContext(myContext)

  function changeName() {
    proDispatch([
      'set',
      {
        name: 'The name of the descendant component has been changed',
      },
    ])
  }

  return (
    <div>
      <h4>Descendant component: </h4>
      <button onClick={changeName}>A descendant component modifies the of a parent component name</button>
      <p>Components passed from parent to child name: {name}</p>
      <hr />
    </div>
  )
}

export default ChildrenCom

4, The function that the parent calls the child

If you want to call a function of a child component in a parent component, or use a value of a subcomponent, you can use this method (as little as possible).

A text description of react's official website:
useImperativeHandle allows you to customize the instance values exposed to the parent component when using ref. In most cases, you should avoid using imperative code such as ref. useImperativeHandle should be used with forwardRef

1. Parent component
import React, { useRef } from 'react'

import ChildrenCom from './child'

// Parent component
const ParentCom = () => {
  // Get sub component instance
  const childRef = useRef()

  // Call the onChange method of the subcomponent
  const onClickChange = () => {
    childRef.current.onChange()
  }

  return (
    <div>
      <h2>Parent component</h2>
      <button onClick={onClickChange}>Click to call sub component onChange function</button>
      <ChildrenCom ref={childRef} demonName="demo1" />
    </div>
  )
}

export default ParentCom
2. Subcomponents
import React, {
  useState,
  useEffect,
  useImperativeHandle,
  forwardRef,
} from 'react'

// Subcomponents
const ChildrenCom = forwardRef((props, ref) => {
  const [value, setValue] = useState(0)
  const [name, setName] = useState('A.Liang')
  const { demonName } = props

  useEffect(() => {
    console.log('ref==>', ref)
  })

  // Customize the instance value exposed to the parent component (useImperativeHandle should be used with forwardRef)
  useImperativeHandle(ref, () => ({
    // Expose function calls to parent components
    onChange,
    // You can also expose the state value of the child component to the parent component
  }))

  const onChange = () => {
    setValue(value + 1)
    setName(name === 'A.Liang' ? 'simon' : 'A.Liang')
  }

  return (
    <div>
      <h4>Subcomponents: {demonName}</h4>
      <p>Of subcomponents value: {value}</p>
      <p>Of subcomponents name: {name}</p>
      <button onClick={onChange}>Click Change value and name</button>
    </div>
  )
})

export default ChildrenCom

Code download (* p-hook * * branch): https://gitee.com/staraliang/react17-app/tree/p-hook/

I think this article is well written. I hope to praise, collect and pay more attention. I will update the dry goods from time to time every month. Thank you!

Articles you may be interested in:

Keywords: Javascript Front-end React

Added by DaiWelsh on Thu, 27 Jan 2022 22:35:17 +0200