在我使用自己构建的自定义插件完成操作之前,我一直在其中一个组件上使用jquery表情符号插件。
由于某种原因,当我在componentDidMount内部调用emoji插件时,一切正常。例外是利用自定义按钮显示emoji模态的功能。当我使用自定义按钮时,表情符号插件不会将事件附加到按钮上。
疯狂的是,我可以在useEffect中使用相同的代码,并将事件侦听器附加到自定义按钮上。
我通过在网页控制台中查看页面加载后附加到元素的事件来验证未附加事件侦听器。
通过将组件放置在应用程序中的某个位置(并使用emoji-area plugin导入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' />
</>
)
}
只需将其更改为类组件,您就会发现在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;
答案 0 :(得分:6)
componentDidMount
和useEffect
触发之间有区别。
来自useEffect文档:
与componentDidMount和componentDidUpdate不同,该函数已传递 在布局和绘制后使用
使用效果效果
答案 1 :(得分:5)
componentDidMount
和useEffect
之间的最大区别是useEffect
在每个渲染之后运行,而不仅仅是第一个。由于您的render
在每个渲染上都会输出一个 new 元素,因此在第一个渲染DOM元素之后,您附加的emoji表情不再存在,而具有相同ID的新表情
选项:
componentDidUpdate
处理后续渲染。 (第一个仍然需要componentDidMount
。)