美文网首页
useEventEmitter

useEventEmitter

作者: skoll | 来源:发表于2020-09-11 10:39 被阅读0次

事件通信

1 .对于子组件通知父组件的情况,我们仍然推荐直接使用 props 传递一个 onEvent 函数
2 .而对于父组件通知子组件的情况,可以使用 forwardRef 获取子组件的 ref ,再进行子组件的方法调用
3 .useEventEmitter 适合的是在距离较远的组件之间进行事件通知,或是在多个组件之间共享事件通知
4 .我可以再全局注册一些变量值,想要执行事件的时候就触发这个值,希望响应的组件订阅这个值,但是这样的话不能传参,好像还是不行.或者需要两个值,一个确定是否变化,一个确定要传的参数

import {useRef,useEffect} from 'react'

type Subscription<T> = (value:T) => void

export default function useEventEmitter<T = void>(){
    const ref=useRef(new Set<Subscription <T>>())

    function emit(value:T){
        for(const sub of Array.from(ref.current)){
            sub(value)
            // set类型不能遍历,需要先转为数组才行
        }
    }
    //触发绑定的函数的渲染

    function useSubscriptions(callback:Subscription<T>){
        const callbackRef=useRef<Subscription<T>>()
        callbackRef.current=callback

        useEffect(()=>{
            function subscrition(value:T){
                if(callbackRef.current){
                    callbackRef.current(value)
                }
            }
            console.log(subscrition)
            ref.current.add(subscrition)
            return ()=>{
                // 这里的符号搞错了。。。尼玛用了反括号
                ref.current.delete(subscrition)
            }    
        },[])
    }

    return {
        emit,
        useSubscriptions,
    }   
}

import useEventEmitter from '../useEventEmitter'

export default function(){

  const MessageBox = function(props:any) {
    return (
      <div
        style={{
          paddingBottom: 24,
        }}
      >
        <p>You received a message</p>
        <button
          type="button"
          onClick={() => {
            props.focus$.emit({name:123});
          }}
        >
          Reply
        </button>
      </div>
    );
  };
  
  const InputBox = function(props:any) {
    const inputRef = useRef<HTMLInputElement>(null);
    props.focus$.useSubscriptions((value:any) => {
      if(inputRef.current){
        inputRef.current.focus();
        console.log(value)
      }
    });
    return (
      <input
        ref={inputRef}
        placeholder="Enter reply"
        style={{
          width: '100%',
          padding: '4px',
        }}
      />
    );
  };
  const InputBoxA = function(props:any) {
    const inputRef = useRef<HTMLInputElement>(null);
    props.focus$.useSubscriptions((value:any) => {
      if(inputRef.current){
        inputRef.current.focus();
        console.log(value)
      }
    });
    return (
      <input
        ref={inputRef}
        placeholder="Enter reply"
        style={{
          width: '100%',
          padding: '4px',
        }}
      />
    );
  };

  const focus$ = useEventEmitter();
  console.log(focus$)
  return (
    <>
      <MessageBox focus$={focus$} />
      <InputBox focus$={focus$} />
      <InputBoxA focus$={focus$} />
    </>
  );
}

相关文章

  • useEventEmitter

    事件通信 1 .对于子组件通知父组件的情况,我们仍然推荐直接使用 props 传递一个 onEvent 函数2 ....

网友评论

      本文标题:useEventEmitter

      本文链接:https://www.haomeiwen.com/subject/qskeektx.html