react-数据流总结
跨组件调用方法
1 .A组件调用B组件的方法.header做了操作,需要content组件来响应
2 .最简单的就是定义一些值,如果某些值变化,就调用某些函数.但是这个维护起来简直爆炸.还有就是不能传参数
3 .props调用,这种只适合父子组件,兄弟,子孙的传起来也是爆炸,兄弟组件就是通过服组件来操作
4 .useRef
props(父-子)
Instance Methods(父-子)
1 .父组件可以通过使用refs来直接调用子组件实例的方法,看下面的例子
2 .比如子组件是一个modal弹窗组件,子组件里有显示/隐藏这个modal弹窗的各种方法,我们就可以通过使用这个方法,直接在父组件上调用子组件实例的这些方法来操控子组件的显示/隐藏。这种方法比起你传递一个控制modal显示/隐藏的props给子组件要美观多了
3 .useRef使用
//父元素向子元素挂载ref的方法
function App(){
const ref=useRef()
const [isTrue,setIsTrue]=useState(false)
useEffect(()=>{
if(isTrue){
//现在应该可以访问ref了
content.current.resetCount()
}
},[isTrue])
return (
<div>
<Content ref={(el)=>{
ref.current=el
setIsTrue(true)
}}/>
</div>
)
}
//子元素
function Content(props,ref){
//注意这里要加一个ref来接收
useImperativeHandle(ref,()=>{
resetCount:resetCount
//这里面放可以被父元素调用的子元素的函数
}))
}
Cllback Functions(子-父)
1 .这种看起来就像是props方式吧
const Child = ({ onClick }) => {
<div onClick={() => onClick('zach')}>Click Me</div>
}
class Parent extends React.Component {
handleClick = (data) => {
console.log("Parent received value from child: " + data)
}
render() {
return (
<Child onClick={this.handleClick} />
)
}
}
Event Bubbing
1 .利用原生DOM元素的事件冒泡机制
class Parent extends React.Component {
render() {
return (
<div onClick={this.handleClick}>
<Child />
</div>
);
}
handleClick = () => {
console.log('clicked')
}
}
function Child {
return (
<button>Click</button>
);
}
2 .但是这种的,如果里面还有子元素有点击事件,怎么区分哪个是那个触发的呢
奇怪bug
1 .这种写法为啥数据变了,视图没有变呢,感觉是react做了自己的缓存,但是key可以看到是完全不一样的啊.
return <div
className="right-number-input"
key={id}
>
<span className="right-input-title">{name}</span><InputNumber
defaultValue={values[key[0]]}
min={-10000}
max={10000}
onChange={(e)=>handleNumberInput(e,key[0])}
/>
</div>
2 .问题刨析,input组件我这里不仅写了defaultvalue,还写了value
3 .setState()的时候是一个对象,没有使用
setValues(Object.assign({},values))
setValues(values))
//这种提交因为values是一个对象,所以不会触发渲染,所以页面上还是旧的值,没有刷新.
非父子组件通信方法
1 .跨组件调用它的函数,和通信感觉还不是一个东西
2 .利用effect可以做一个鉴测机制,检测到之前约定好的值,就调用对应的函数,算是一个拐弯的做法,但是还是不如直接调用某个函数方便吧.
3 .先看是否是兄弟组件,如果非父组件,就用一个组件包起来从而变成兄弟i组件,然后利用父组件作为中间层进行通信
4 .还是不符合任意两个组件之间的函数调用要怎么操作呢
Context
1 .前端的一些全局性置的数据,当前登陆的用户信息,ui主题,这些全局数据,很多数据都会用到
2 .context可以传递函数,但是这个是用来改变自己的值得,并不是某一个组件的函数,怎么办.
全局变量
1 .直接把变量挂载在window上面
观察者模式
A组件监听一个事件
useEffect(()=>{
document.addEventListener('delete',(data)=>{
console.log('content delete',data)
//调用的事件,以及触发的时候传过来的参数
})
return function(){
document.removeEventListener('delete',()=>{
console.log('卸载事件')
})
}
},[])
B组件触发事件
function handleTest(){
console.log('test')
document.dispatchEvent(new CustomEvent('delete',{
detail:{
log:"拉拉"
}
}))
}
2 .问题,目前事件都绑定在了documnet上面,最好是单独建一个事件来操作
class EventBus {
constructor() {
this.bus = document.createElement('fakeelement');
}
addEventListener(event, callback) {
this.bus.addEventListener(event, callback);
}
removeEventListener(event, callback) {
this.bus.removeEventListener(event, callback);
}
dispatchEvent(event, detail = {}){
this.bus.dispatchEvent(new CustomEvent(event, { detail }));
}
}
export default new EventBus
3 .自己实现一个观察者模式