亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

React 生命周期內文檔上的 React Keyup 事件

React 生命周期內文檔上的 React Keyup 事件

達令說 2023-07-14 14:45:57
據我了解,refs 不是在 React 生命周期(source)之外定義的。我試圖解決的問題是捕獲文檔級別的按鍵(即,無論聚焦哪個元素都觸發事件),然后與反應引用交互。下面是我正在嘗試做的事情的簡化示例:export default 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={true}>{this.state.text}</textarea>? ? ? ? ? ? ? ? </div>? ? ? ? ? ? </footer>? ? ? ? );? ? }}class App extends React.Component {? private console: Console;? constructor() {? ? super({});? ??? ? 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" onKeyDown={this.keyDown}> // <-- this only works when this element is in focus? ? ? ? // other that has access to this.console that will call console.print(...)? ? ? ? <Console ref={this.console} />? ? ? </div>? ? );? }}我的問題是:有沒有辦法在 React 的生命周期內進行此類文檔級按鍵,以便 ref 不在undefined事件處理程序內keyDown?我見過很多涉及設置tabIndex和黑客攻擊以確保正確的元素在正確的時間獲得焦點的解決方案,但這些對我來說似乎并不是可靠的解決方案。我剛剛學習 React,所以這可能是 React 的設計限制,或者我沒有正確設計我的組件。但這種功能對我來說似乎相當基本,能夠將組件從一個組件傳遞到另一個組件并相互調用方法。
查看完整描述

1 回答

?
大話西游666

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>

? );

};


查看完整回答
反對 回復 2023-07-14
  • 1 回答
  • 0 關注
  • 174 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號