react数据通信
父子组件通信
父传子:父组件可以通过 props将数据传给子组件,子组件可以使用 props 来读取数据
子传父:父组件给子组件传递一个回调函数(本质上也是props,只不过这个props是函数),然后在子组件中调用这个函数
props的使用
- 要传递
props
,请将它们添加到JSX
,就像使用 HTML 属性一样。 - 要读取 props,请使用
function Avatar({ person, size })
解构语法。 - 你可以指定一个默认值,如
size = 100
,用于缺少值或值为undefined
的 props 。 - 你可以使用
<Avatar {...props} />
JSX
展开语法转发所有props
,但不要过度使用它! - 像
<Card><Avatar /></Card>
这样的嵌套 JSX,将被视为 Card 组件的children prop
。 - Props 是只读的时间快照:每次渲染都会收到新版本的 props。
- 你不能改变 props。当你需要交互性时,你可以设置 state。
子组件给父组件传递数据示例:
import { useState } from "react"
let count = 0
const Son = ({onGetMsg}) => {
console.log('子组件渲染');
return <>
<h2>Son子组件</h2>
<button onClick={() => onGetMsg('hello father' + count++)}>子向父专递信息</button>
</>
}
export default function App () {
const [msgFromSon, setMsgFromSon] = useState('')
const getMsg = (msg) => {
setMsgFromSon(msg)
}
return <>
<h1>父向子传递函数</h1>
<span>父组件获取的信息为:{msgFromSon}</span>
<Son onGetMsg={getMsg}></Son>
</>
}
在上面的例子中,当点击子组件的button时,父组件都会更新一次,同时子组件也会一起更新。在react中,如果父组件更新,那么子组件也会更新,有时候为了避免这种情况,可以搭配使用useCallback(缓存函数)、useMemo(缓存数据)、memo(缓存组件)
使用,来避免不必要的子组件更新。上面的例子可以做如下修改:
import { useCallback, useState, memo } from "react"
let count = 0
const Son = memo(({person, onGetMsg}) => {
console.log('子组件渲染');
return <>
<h2>Son子组件</h2>
<span>父组件传递过来的对象person: {JSON.stringify(person)}</span>
<button onClick={() => onGetMsg('hello father' + count++)}>子向父专递信息</button>
</>
})
export default function App () {
const [msgFromSon, setMsgFromSon] = useState('')
const getMsg = useCallback((msg) => {
setMsgFromSon(msg)
}, [])
const person = useMemo(() => ({
name: 'LiLy',
age: 10
}), [])
return <>
<h1>父向子传递函数</h1>
<span>父组件获取的信息为:{msgFromSon}</span>
<Son person={person} onGetMsg={getMsg}></Son>
</>
}
上面例子,在点击子组件的按钮时,父组件App会更新,但是由于子组件依赖的输入都未发生改变,所以子组件未更新。
兄弟组件通信
使用状态提升实现兄弟组件通信,把需要通信的变量提升到共同的父组件中。
跨层传递数据 通过createContext
createContext
的用法:
// Contexts.js 创建context
import { createContext } from 'react';
export const ThemeContext = createContext('light');
export const AuthContext = createContext(null);
// Button.js 消费者
import { ThemeContext } from './Contexts.js';
function Button() {
const theme = useContext(ThemeContext);
// ...
}
// App.js 数据提供者
import { ThemeContext, AuthContext } from './Contexts.js';
function App() {
// ...
return (
<ThemeContext.Provider value={theme}>
<AuthContext.Provider value={currentUser}>
<Page />
</AuthContext.Provider>
</ThemeContext.Provider>
);
}
转载自:https://juejin.cn/post/7367229542934118454