做项目遇到的情况,在useEffect中对一个元素进行事件绑定:
useEffect(() => {
// 处理键盘键盘事件
(document.getElementsByClassName('md-editor-panel')[0] as HTMLElement)
.onkeydown = handleKeydown;
}, []);
其中用到的其他方法和数据如下:
// 键盘事件处理函数
const handleKeydown = (e: KeyboardEvent) => {
// 处理tab事件
if (e.code === 'Tab') {
e.preventDefault();
const str = '\t';
const obj = e.target as HTMLTextAreaElement;
if (document.selection) {
var sel = document.selection.createRange();
sel.text = str;
} else if (typeof obj.selectionStart == 'number'
&& typeof obj.selectionEnd == 'number') {
var startPos = obj.selectionStart, endPos = obj.selectionEnd, cursorPos = startPos, tmpStr = obj.value;
obj.value = tmpStr.substring(0, startPos) + str
+ tmpStr.substring(endPos, tmpStr.length);
cursorPos += str.length;
obj.selectionStart = obj.selectionEnd = cursorPos;
} else {
obj.value += str;
}
}
// console.log(e)
// 处理ctrl+s事件
if (e.ctrlKey === true && e.code === 'KeyS') {
e.preventDefault();
handleSaveDraft();
}
};
function handleSaveDraft() {
console.log('保存', articleInfo);
// if (!articleInfo.articleName ||
// !articleInfo.content ||
// !articleInfo.articleName.trim() ||
// !articleInfo.content.trim()) {
// notification.error({
// message: '文章标题和内容空缺'
// });
// return;
// }
// let res = saveDraft(articleInfo);
}
其中articleInfo
是一个state hook定义的状态
type Article = {
aid: Number | null,
articleName: String | null,
authorId: Number | null,
authorUsername: String | null,
content: String | null,
description: String | null,
isOriginal: Number | null,
isDraft: Number | null,
cover: String | null
}
const [articleInfo, setArticleInfo] = useState<Article>({
aid: null,
articleName: null,
authorId: null,
authorUsername: null,
content: null,
description: null,
isOriginal: null,
isDraft: null,
cover: null
}); // 当前编辑文章的信息
在后期组件运行的时候,使用了setState方法(setArticleInfo)更改了数据状态,再更改后获取articleInfo
可以获取到正常值
setArticleInfo(Object.assign({}, articleInfo, {
content: text
}));
但是在事件处理函数调用的handleSaveDraft
方法中只能获得articleInfo
的初始值:
原因是useEffect
在进行初始化时,绑定了初始对象,但是后期经过setState
之后articleInfo
的指向发生变化。这个问题暂时没有解决。
暂时使用useEffect
的updated钩子,即去掉第二个参数,让其每次articleInfo
更新后都执行,即每次绑定的作用域的articleInfo
都是当前的对象。这样写代码属于是笨方法,好在页面不是很复杂,不然会影响效率。如果后期有解决方案再回来补上。
useEffect(() => {
// 处理键盘键盘事件
(document.getElementsByClassName('md-editor-panel')[0] as HTMLElement)
.onkeydown = handleKeydown;
}, [articleInfo]);