Reactjs React/TypeScript:创建一个统一的;“通知”;与单个组件关联的函数

Reactjs React/TypeScript:创建一个统一的;“通知”;与单个组件关联的函数,reactjs,typescript,Reactjs,Typescript,我正在尝试设计我的应用程序,以便将所有通知绑定到一个包装应用程序的“snackbar”样式组件(我使用的是material UI snackbar组件): 范例 class App extends React.Component { public render() { return ( <MySnackbar > <App /> <MySnackbar /> } } 我知道有些库可以做到这一点,但对我来

我正在尝试设计我的应用程序,以便将所有通知绑定到一个包装应用程序的“snackbar”样式组件(我使用的是material UI snackbar组件):

范例

class App extends React.Component {
  public render() {
    return (
      <MySnackbar >
        <App />
      <MySnackbar />
  }
}
我知道有些库可以做到这一点,但对我来说,在使用它们之前了解它们是如何工作的是很重要的。我见过一些使用全局状态(redux、react-context)的示例,但我希望避免使用全局状态


我曾尝试过遵循一些关于创建HOC模式的指南,但我似乎无法设计出我想要的工作方式。我想做的技术上可行吗?我知道我可以通过将函数作为道具传递给每个孩子来实现这一点,但这需要在每个接口和中间组件中添加一个字段,而且不是很枯燥。

Stable React的方法是
上下文
()

接口IContext{
updateMessage:(newMessage:string)=>void;
}
接口IProps{}
界面状态{
消息:字符串;
}
const SnackbarContext=React.createContext({
updateMessage:()=>{},
});
类Snackbar扩展了React.Component{
建造师(道具){
超级(道具);
此.state={
消息:“”,
};
this.updateMessage=this.updateMessage.bind(this);
}
render(){
返回(
消息:{this.state.MESSAGE}

{this.props.children} ); } updateMessage(新消息:字符串){ this.setState({message:newMessage}); } } 子类扩展了React.Component{ 静态contextType:React.Context=SnackbarContext; 语境:IContext; 建造师(道具){ 超级(道具); this.onButtonClick=this.onButtonClick.bind(this); } render(){ 返回( 创建消息 ); } onButtonClick(){ this.context.updateMessage(`Message末尾带有随机数${Math.random()}`); } }
还有一个实验()可能是也可能不是未来

我曾尝试过遵循一些创建HOC模式的指南,但我似乎无法设计一些东西

HOC在这里不起作用。或者所有JSX.element都需要用HOC包装。而且,在整个元素树中传递回调函数比使用HOCs更容易

class MySnackbar extends React.Component<object, State> {
  public state = {
    currentMessage: { message: "", key: 0},
    open: false
  };
  private messageQueue = [];

  public openAlert = (message: string) => {
    this.queue.push({ key: new Date().getTime(), message})
    if (!this.state.open) {
      this.setState({ open: true });
    }
  }
  // other class methods...
  public render () {
    // render component here...
  }
} 
import notificationFunction from "MySnackbar";

class Child extends React.Component {
  public notifyUser = () => {
    notificationFunction("Hi user!")
  }
}
interface IContext {
  updateMessage: (newMessage: string) => void;
}

interface IProps {}

interface IState {
  message: string;
}

const SnackbarContext = React.createContext<IContext>({
  updateMessage: () => {},
});

class Snackbar extends React.Component<IProps, Partial<IState>> {
  constructor(props) {
    super(props);
    this.state = {
      message: "",
    };

    this.updateMessage = this.updateMessage.bind(this);
  }

  render() {
    return (
      <SnackbarContext.Provider value={{ updateMessage: this.updateMessage }}>
        <div>
          <strong>MESSAGE:</strong> {this.state.message}
        </div>
        <hr />
        {this.props.children}
      </SnackbarContext.Provider>
    );
  }

  updateMessage(newMessage: string) {
    this.setState({ message: newMessage });
  }
}

class Child extends React.Component {
  static contextType: React.Context<IContext> = SnackbarContext;
  context: IContext;

  constructor(props) {
    super(props);

    this.onButtonClick = this.onButtonClick.bind(this);
  }

  render() {
    return (
      <div>
        <button onClick={this.onButtonClick}>Create message</button>
      </div>
    );
  }

  onButtonClick() {
    this.context.updateMessage(`Message with random number at the end ${Math.random()}`);
  }
}

<Snackbar>
  <Child />
</Snackbar>