使用jQuery Emoji插件时,componentDidMount与useEffect的行为不同

sil*_*ood 7 javascript emoji reactjs

我被困在其中一个组件上使用jquery表情符号插件,直到完成要构建的自定义插件。

出于某种原因,当我在componentDidMount内调用emoji插件时,使用自定义按钮显示emoji模态的功能,其他所有东西都起作用。当我使用自定义按钮时,表情符号插件不会将事件附加到按钮上。

疯狂的是,我可以在useEffect中使用相同的代码,并将事件侦听器附加到自定义按钮上。

通过在Web控制台中查看页面加载后附加到元素的事件,我验证了事件监听器是否未附加。

您可以通过将此组件放置在应用程序中的某个位置(并使用emoji-area插件导入jquery)来轻松重现此问题:

import React, {useEffect} from 'react';

  export default function CommentInput(props) {

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


      $.emojiarea.path = '/js/jquery/emojis/';
      $.emojiarea.icons = {
        ':smile:'     : 'smile.png',
        ':angry:'     : 'angry.png',
        ':flushed:'   : 'flushed.png',
        ':neckbeard:' : 'neckbeard.png',
        ':laughing:'  : 'laughing.png'
      };

   }, []); 

   return (
     <>
        <textarea id={props.blurtId} className='blurt-comment-input' />
        <i id={'emoji-btn' + props.blurtId} className='fa fa-smile emoji-btn' />  
     </>
   )

}
Run Code Online (Sandbox Code Playgroud)

只需将其更改为类组件,您就会看到在componentDidMount中,除自定义按钮外,所有其他东西都起作用。知道什么会导致这种行为改变吗?

这是react类组件的版本:

import React, {Component} from 'react';

class CommentInput extends Component {

constructor(props) {
    super(props);
}

componentDidMount() {
    const id = this.props.blurtId,
          $wysiwyg = $('#' + id).emojiarea({
            button: '#emoji-btn' + id
        });


    $.emojiarea.path = '/js/jquery/emojis/';
    $.emojiarea.icons = {
        ':smile:'     : 'smile.png',
        ':angry:'     : 'angry.png',
        ':flushed:'   : 'flushed.png',
        ':neckbeard:' : 'neckbeard.png',
        ':laughing:'  : 'laughing.png'
    };
}; 

render() {
    return (
        <>
            <textarea id={this.props.blurtId} className='blurt-comment-input' />
            <i id={'emoji-btn' + this.props.blurtId} className='fa fa-smile emoji-btn' />  
        </>
      )
    }
}

export default CommentInput;
Run Code Online (Sandbox Code Playgroud)

Moh*_*ami 6

when componentDidMountuseEffectfire 之间有区别。

从useEffect文档:

与componentDidMount和componentDidUpdate不同,传递给useEffect的函数在布局和绘制后触发


T.J*_*der 5

componentDidMount和之间的最大区别useEffect是,useEffect每次渲染后运行,而不仅仅是第一个。由于您在每个渲染上都render输出了一个元素,因此在第一个渲染DOM元素之后,您附加的emoji表情不再存在,而具有相同ID的新元素就不再存在。

选项: