useEffect中调用的方法,只能访问到useState的初始值,不能访问到setState过后的值(未解决)

做项目遇到的情况,在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]);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值