通信

props

函数(标签上传递,参数接收)

interface IProps {
  name: string
}
interface IState {}
function Comp(props: IProps) {
  const [state, setState] = useState<IState>({})  //这属于hooks内容,在函数组件中初始化state
  return <h1>my name is {props.name}</h1>
}
const name = 'LLC'
ReacrDOM.render(<Comp  name={name} />, document.getElementById('app'))

类(defaultProps传递 / 标签上传递,this.props接收)

class Comp extends React.Component<IProps, IState> {
  constructor(props: IProps) {
    super(props)
    this.state = {}
  }
  render() {
    return <h1>my name is {this.props.name}</h1>
  }
}
Comp.defaultProps = {
  name: 'LLC'
}
ReacrDOM.render(<Comp/>, document.getElementById('app'))

props传递方法(父向子传递函数,由子触发,从而实现子向父传递数据)

class Father extends React.Component {
  state = {
    needToDo: ["wash cloth", "do housework"],
  };
  getTask = (event) => {
    const { needToDo } = this.state;
    needToDo.unshift(event);
    this.setState({ needToDo });
  };
  render() {
    return (
      <div>
        <h1>老爸需要做的事情:</h1>
        <ul>
          {this.state.needToDo.map((e, index) => {
            return <li key={index}>{e}</li>;
          })}
        </ul>
        <h1>再安排些事情给老爸做:</h1>
        <Son assgin={this.getTask} />
      </div>
    );
  }
}

class Son extends React.Component {
  assginTask = () => {
    this.props.assgin(this.refs.inp.value);
    this.refs.inp.value = "";
  };
  render() {
    return (
      <div>
        <input ref="inp" />
        <button onClick={this.assginTask}>安排</button>
      </div>
    );
  }
}

createContext/consumer,对标provider/inject

这和直接import的区别就是,这是可以传响应式数据,import的话,虽然是改了,但是在页面中不是实时渲染的

import { createContext, useState } from "react";

export const aProvider = createContext();

export default function GrandPa() {
  const [num, setNum] = useState(10);
  return (
    <>
      <button
        onClick={() => {
          setNum(110);
        }}
      >
        increment num
      </button>
      <aProvider.Provider value={{ num, setNum }}>
        <Father />
      </aProvider.Provider>
      ;
    </>
  );
}

const Father = () => <Child />;

// 如果不在同一个文件下,还要再import aProvider from 'xxx/GrandPa'
function Child() {
  return (
    <>
      <h1>I am Child</h1>
      <aProvider.Consumer>
        {({ num, setNum }) => {
          return (
            <>
              <p>{num}</p>
              <button
                onClick={() => {
                  setNum(120);
                }}
              >
                increment num to 120
              </button>
            </>
          );
        }}
      </aProvider.Consumer>
    </>
  );
}

useRef + forwardRef 对标 $refs(函数组件没有实例,只能在类组件用)

funtion Father() {
  const 拿来吧你= useRef(null)
  // 直接拿到了子组件实例,然后就可以为所欲为
  return <Kid ref={拿来吧你} />
}

class Kid extends React.Component {
  state = {
    name: 'kid'
  }
  render() {
    return <h1>{this.state.name}</h1>
  }
}
更牛的是,Father中的 “拿来吧你” 竟然可以做props,传递出去,拿其它非子组件的实例(通信能通到哪,就能拿到哪)
funtion 表哥(props) {
  return <表哥的大舅 ref={props.拿来吧你} />  // 这就“千里之外”拿到了表哥的大舅的实例
}
class 表哥的大舅 extends React.Component {}

创建自定义事件传值 对标 eventBus

可以把document当成那个bus,但是这很艹蛋,故创建一个不用的伪元素来做事件中心

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

import EventBus from './EventBus'
class ComponentA extends React.Component {
    componentDidMount() {
        EventBus.addEventListener('myEvent', this.handleEvent)
    }
    componentWillUnmount() {
        EventBus.removeEventListener('myEvent', this.handleEvent)
    }   
    handleEvent = (e) => {
        console.log(e.detail.log)  //i'm zach
    }
}
class ComponentB extends React.Component {
    sendEvent = () => {
        EventBus.dispatchEvent('myEvent', {log: "i'm zach"}))
    }   
    render() {
        return <button onClick={this.sendEvent}>Send</button>
    }
}

posted on 2022-10-06 23:27  In-6026  阅读(21)  评论(0编辑  收藏  举报

导航