在事件监听器中使用useState()时遇到麻烦。看不到更新状态

时间:2019-08-26 17:45:50

标签: javascript reactjs

不幸的是,我在我的一个组件上卡住了一些jquery(直到我完成自定义的emoji插件)。

我有一个jQuery表情符号库,可创建一个内容可编辑的div来代替文本区域。为了在编辑器中获取用户输入,我监听了编辑器change事件,并相应地设置了状态,并利用了监听器中的状态设置器。问题是,我没有看到我的状态更新。这是代码:

const [newComment, setNewComment] = useState('');

    const logComment = function(event) {
        if (event.key == 'Enter') {
            console.log(newComment);
        }
    }

    const setComment = function() {
        console.log($(this).val());
        setNewComment($(this).val());
    }

    useEffect(() => {
        setNewComment('hey');
        const id = props.blurtId,
              $wysiwyg = $('#' + id).emojiarea({
                button: '#emoji-btn' + id
            });

        // Calls method to set comment state.
        $wysiwyg.on('change', setComment);

        // Logs state to console when user presses enter.
        window.addEventListener('keydown', logComment);
    }, []);

$(this).val()正确地登录到每个change的屏幕上。但是,当我按Enter键时,它只是将初始空白值记录到屏幕上,就像状态从未被更新一样。

注意:另外,我尝试仅在useEffect开头将状态设置为“嘿”,但仍然没有明显的状态更新。

2 个答案:

答案 0 :(得分:1)

每次重新渲染组件时,都会重新定义函数logCommentsetComment,这就是使用函数组件的钩子的工作方式。由于您在useEffect中没有依赖项,因此它将使用logComment的较旧定义,而显示的是newComment的较旧版本。

changekeypress事件是不同的效果(一个事件用于记录另一个事件来设置状态?),您应该通过在{{1}中拆分代码来定义自己的效果},分为两部分:

useEffect(...

另一个问题是是否有意义。

答案 1 :(得分:1)

建议在使用钩子react-hooks eslint插件时安装:https://www.npmjs.com/package/eslint-plugin-react-hooks

每次有一个新的渲染时都会定义logComment,所以我将其分离到组件外部,仍然可以重新定义它,但是为了更好地理解心理模型,让我们以它为例进行操作

const logComment = newComment => event => {
  if (event.key == "Enter") {
    console.log(newComment);
  }
};

在功能组件中,您向newComment添加了一个依赖项,该依赖关系在setComment上的大小写发生变化时会更新。另外,由于要在useEffect中添加事件侦听器,因此应通过返回删除侦听器的函数进行清理。

const [newComment, setNewComment] = useState("");

const setComment = function() {
  console.log($(this).val());
  setNewComment($(this).val());
};

useEffect(() => {
  const id = props.blurtId,
    $wysiwyg = $("#" + id).emojiarea({
      button: "#emoji-btn" + id
    });

  // Calls method to set comment state.
  $wysiwyg.on("change", setComment);

  const newLogger = logComment(newComment);

  // Logs state to console when user presses enter.
  window.addEventListener("keydown", newLogger);

  return () => window.removeEventListener("keydown", newLogger);

}, [newComment]);

我创建了一个使用click事件的示例,该示例与您的示例代码有些相似,但是没有其他库:https://codesandbox.io/s/affectionate-wright-funj3