react-数据流总结

2022-01-26  本文已影响0人  skoll

跨组件调用方法

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 .自己实现一个观察者模式

上一篇下一篇

猜你喜欢

热点阅读