我正在尝试设计我的应用程序,以使所有通知都绑定到一个包装应用程序的单个“ snackbar”样式组件(我使用的是材料UI快餐栏组件):
示例
class App extends React.Component {
public render() {
return (
<MySnackbar >
<App />
<MySnackbar />
}
}
被截断的小吃店类示例:
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...
}
}
我试图弄清楚如何做到这一点,以便我可以简单地导出一个在调用时可以访问引用父小吃栏的“ openAlert”功能的函数。
假设的子组件:
import notificationFunction from "MySnackbar";
class Child extends React.Component {
public notifyUser = () => {
notificationFunction("Hi user!")
}
}
我知道有很多库可以做到这一点,但是对于我来说重要的是在使用库之前了解它们是如何工作的。我已经看到了一些使用全局状态(redux,react-context)的示例,但我希望避免为此使用全局状态。
我尝试遵循一些有关创建HOC模式的指南,但是我似乎无法设计出一些我希望它能起作用的方法。从技术上来说,我正在尝试做的事吗?我知道我可以通过将函数作为道具传递给每个孩子来完成这项工作,但这需要向每个接口和中间组件中添加一个字段,并且不是很干。
答案 0 :(得分:1)
稳定React的做法是Context
(https://reactjs.org/docs/context.html)。
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>
还有钩子实验(https://reactjs.org/docs/hooks-intro.html),它可能是未来,也可能不是未来。
我尝试遵循一些有关创建HOC模式的指南,但是我似乎无法设计一些东西
HOC在这里不起作用。否则所有JSX.Elements将需要包装在HOC中。而且,将回调函数向下传递到整个元素树而不是使用HOC更容易。