1 回答
TA贡献1817条经验 获得超14个赞
您将调用 onKeyDown 回调两次,一次在文档上,一次在应用程序上。事件在树上冒泡。当textarea没有焦点时,onlydocument.onkeydown
被调用。当它处于焦点时,document.onkeydown
和 Appdiv.onkeydown
都会被调用,从而有效地取消效果(切换状态关闭和重新打开)。
这是一个工作示例:https://codesandbox.io/s/icy-hooks-8zuy7 ?file=/src/App.js
import React from "react";
class Console extends React.Component {
constructor(props) {
super(props);
this.state = {
visible: false,
text: ""
};
}
print(output: string) {
this.setState({
text: this.state.text + output + "\n"
});
}
toggleVisible() {
this.setState({ visible: !this.state.visible });
}
render() {
const footer_style = {
display: this.state.visible ? "inline" : "none"
};
return (
<footer
id="console-footer"
className="footer container-fluid fixed-bottom"
style={footer_style}
>
<div className="row">
<textarea id="console" className="form-control" rows={5} readOnly>
{this.state.text}
</textarea>
</div>
</footer>
);
}
}
export default class App extends React.Component {
constructor(props) {
super(props);
this.console = React.createRef();
}
keyDown = (e) => {
this.console.current.toggleVisible(); // <-- this is undefined
};
componentDidMount() {
document.addEventListener("keydown", this.keyDown);
}
componentWillUnmount() {
document.removeEventListener("keydown", this.keyDown);
}
render() {
return (
<div className="App" style={{ backgroundColor: "blueviolet" }}>
enter key to toggle console
<Console ref={this.console} />
</div>
);
}
}
另外,我建议使用React 的 hooks:
export default App = () => {
const console = React.createRef();
const keyDown = (e) => {
console.current.toggleVisible(); // <-- this is undefined
};
React.useEffect(() => {
// bind onComponentDidMount
document.addEventListener("keydown", keyDown);
// unbind onComponentDidUnmount
return () => document.removeEventListener("keydown", keyDown);
});
return (
<div className="App" style={{ backgroundColor: "blueviolet" }}>
press key to toggle console
<Console ref={console} />
</div>
);
};
添加回答
举报