前言
自从react官方引入了hook,很多小伙伴都从老的class组件换为hook组件,但因为hook组件的传参和class组件传参还是有些区别的,所以下文汇总了4种传参方式
一、父传子
子组件通过props接收父组件传来的数据
1、父组件
import React, { useState } from 'react'
import ChildrenCom from './child'
const ParentCom = () => {
const [name] = useState('A.Liang')
return (
<div>
<h2>父组件</h2>
<ChildrenCom name={name} />
</div>
)
}
export default ParentCom
2、子组件
import React, { useState } from 'react'
import ChildrenCom from './child'
import React, { useEffect } from 'react'
const ChildrenCom = props => {
const { name } = props
useEffect(() => {
console.log('props==>', props)
})
return (
<div>
<h4>子组件: </h4>
<p>父传给子组件的name: {name}</p>
</div>
)
}
export default ChildrenCom
二、子传父
父组件props传递回调函数给子组件
如果子组件想向父组件传递某些值,或者是子组件在执行某一段逻辑后想执行父组件中的某一段逻辑,此时可以在父组件中写好对应的逻辑函数,通过props传递这个函数给子组件进行调用即可
1、父组件
import React, { useState } from 'react'
import Child from './child'
const ParentCom = () => {
const [count, setCount] = useState(0)
const getChildrenValue = val => {
setCount(val)
}
return (
<div>
<h2>父组件</h2>
<p>获取子组件传过来的值:{count}</p>
{}
<Child getValue={getChildrenValue} />
</div>
)
}
export default ParentCom
2、子组件
import React, { useState } from 'react'
const ChildrenCom = props => {
const [value, setValue] = useState(0)
const addValue = () => {
setValue(value + 1)
props.getValue(value + 1)
}
return (
<div>
<h4>子组件</h4>
<button onClick={addValue}>点击改变子组件的value值:{value}</button>
</div>
)
}
export default ChildrenCom
三、父传后代
使用useContext 实现跨组件传值
const value = useContext(MyContext);
useContext接收一个 context 对象(React.createContext 的返回值)并返回该 context 的当前值。当前的 context 值由上层组件中距离当前组件最近的 <MyContext.Provider> 的 value prop 决定。
1、context.js
import { createContext } from 'react'
const myContext = createContext(null)
export default myContext
2、父组件
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最顶层组件----实现跨组件间传值。</h1>
<button
onClick={() => {
dispatch(['set', { name: '父组件改变了名字' }])
}}
>
点我修改name
</button>
<br />
父组件-name:{state.name}
<hr />
<myContext.Provider
value={{
name: state.name,
proDispatch: dispatch,
}}
>
{}
<Child />
</myContext.Provider>
</div>
)
}
export default ParentCom
3、子组件
import React, { useContext } from 'react'
import myContext from './createContext'
import ChildChild from './child-child'
const ChildrenCom = () => {
const { name, proDispatch } = useContext(myContext)
function changeName() {
proDispatch([
'set',
{
name: '子组件修改了名字',
},
])
}
return (
<div>
<h4>子组件: </h4>
<button onClick={changeName}>子组件修改父组件的name</button>
<p>父传给子组件的name: {name}</p>
<ChildChild />
<hr />
</div>
)
}
export default ChildrenCom
4、子孙组件
import React, { useContext } from 'react'
import myContext from './createContext'
const ChildrenCom = () => {
const { name, proDispatch } = useContext(myContext)
function changeName() {
proDispatch([
'set',
{
name: '子孙组件修改了名字',
},
])
}
return (
<div>
<h4>子孙组件: </h4>
<button onClick={changeName}>子孙组件修改父组件的name</button>
<p>父传给子孙组件的name: {name}</p>
<hr />
</div>
)
}
export default ChildrenCom
四、父调用子的函数
如果想在父组件中调用子组件的某个函数,或者是使用子组件的某个值,可以使用这个方式(尽量少用)
react官网的一段文字描述: useImperativeHandle 可以让你在使用 ref 时自定义暴露给父组件的实例值。在大多数情况下,应当避免使用 ref 这样的命令式代码。useImperativeHandle 应当与 forwardRef 一起使用
1、父组件
import React, { useRef } from 'react'
import ChildrenCom from './child'
const ParentCom = () => {
const childRef = useRef()
const onClickChange = () => {
childRef.current.onChange()
}
return (
<div>
<h2>父组件</h2>
<button onClick={onClickChange}>点击调用子组件onChange函数</button>
<ChildrenCom ref={childRef} demonName="demo1" />
</div>
)
}
export default ParentCom
2、子组件
import React, {
useState,
useEffect,
useImperativeHandle,
forwardRef,
} from 'react'
const ChildrenCom = forwardRef((props, ref) => {
const [value, setValue] = useState(0)
const [name, setName] = useState('A.Liang')
const { demonName } = props
useEffect(() => {
console.log('ref==>', ref)
})
useImperativeHandle(ref, () => ({
onChange,
}))
const onChange = () => {
setValue(value + 1)
setName(name === 'A.Liang' ? 'simon' : 'A.Liang')
}
return (
<div>
<h4>子组件: {demonName}</h4>
<p>子组件的value: {value}</p>
<p>子组件的name: {name}</p>
<button onClick={onChange}>点击改变value和name</button>
</div>
)
})
export default ChildrenCom
代码下载(*p-hook**分支):https://gitee.com/staraliang/react17-app/tree/p-hook/
觉得本文写的不错的,希望点赞、收藏、加关注,每月不定期更新干货哦,谢谢您嘞!
你可能感兴趣的文章:
|