我有一个像弹出窗口一样显示的Chat
组件。我想让用户有可能打开/关闭它作为更深层次组件的操作。我花了几个小时在上面,因为我将对其他组件使用相同的模式。我真的很感激一个干净/反应的解决方案!
到目前为止,我设法做了一些工作,但看起来真的很笨拙。
EDIT:我做了一个单独的例子,让它看起来更好。仍然想知道React方式是什么。
import React, { Component } from 'react';
var instance = null;
class Chat extends Component {
constructor(props) {
super(props);
this.state = {
show: false
};
}
render() {
return this.state.show ? (<div>CHAT WINDOW</div>) : null;
}
open = () => this.setState({show: true})
close = () => this.setState({show: false})
}
export const openChat = () => instance.open();
export default function ChatSingleton(props) {
if (instance === null)
instance = new Chat(props);
return instance;
}
现在我可以全局调用open
/close
方法,如下所示:
import {openChat} from 'components/Chat';
export default function Foo(props) {
return (<div onClick={openChat}>Open Chat</div>);
}
我在SO上找到了使用Redux或React Context的类似问题的解决方案,但我真的想要一个简单的解决方案。HOC可以。
谢谢!
在寻找解决方案之前,请尝试了解"show"状态是否必须属于chat或他的父亲(责任链模式(一旦你了解了这一点,以下是一些可能的解决方案
使用props:
class Parent extends Component {
constructor(props) {
super(props);
this.state = {
showChat: false
};
}
openChat = () => this.setState({showChat: true})
closeChat = () => this.setState({showChat: false})
render() {
return (
<div>
<Chat show={this.state.showChat}>
<Foo onOpenClick={this.openChat} onCloseClick={this.closeChat}>
</div>
}
}
使用Context:
class MyProvider extends React.Component {
state = {
isOpen: false
};
openChat = e => {
this.setState({ isOpen: true });
};
closeChat = e => {
this.setState({ isOpen: false });
};
render() {
return (
<MyProvider
value={{
state: this.state,
openChat: this.openChat,
openChat: this.closeChat
}}
>
<div >{this.props.children}</div
</MyProvider>
);
}
应用程序:
import { MyProvider } from './ChatContext';
<MyProvider>
<Chat />
<OtherComponent>
<Foo>
</OtherComponent>
</MyProvider>
Foo:
import React, { Component } from 'react';
import { MyConsumer } from './ChatContext';
class Foo extends Component {
state = {};
render() {
return (
<MyConsumer>
{({ openChat }) => (
<div>
This is Foo
<button onClick={openChat}>open</span>
</div>
)}
</MyConsumer>
);
}
}
export default Foo;
阅读有关上下文的更多信息:https://kentcdodds.com/blog/how-to-use-react-context-effectively
或使用React-redux
:https://react-redux.js.org/