admin管理员组文章数量:1023738
I’m stuck using a jquery emoji plugin on one of my ponents until I finish with a custom plugin I’m building.
For some reason, when I call the emoji plugin inside of ponentDidMount, everything works except the ability to utilize a custom button to show the emoji modal. When I use a custom button, the emoji plugin doesn’t attach the event to the button.
What’s crazy is that I can use the same exact code in useEffect, and it attaches the event listener to the custom button just fine.
I verified that the event listener is not attached by looking in the web console at events attached to the element after the page loaded.
You can easily reproduce this problem by placing this ponent somewhere in an app (and importing jquery with the emoji-area plugin):
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-ment-input' />
<i id={'emoji-btn' + props.blurtId} className='fa fa-smile emoji-btn' />
</>
)
}
Simply change this to a class ponent, and you’ll see that within ponentDidMount, everything works except the custom button. Any idea what could cause this change in behavior??
Here is the react class ponent version:
import React, {Component} from 'react';
class CommentInput extends Component {
constructor(props) {
super(props);
}
ponentDidMount() {
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-ment-input' />
<i id={'emoji-btn' + this.props.blurtId} className='fa fa-smile emoji-btn' />
</>
)
}
}
export default CommentInput;
I’m stuck using a jquery emoji plugin on one of my ponents until I finish with a custom plugin I’m building.
For some reason, when I call the emoji plugin inside of ponentDidMount, everything works except the ability to utilize a custom button to show the emoji modal. When I use a custom button, the emoji plugin doesn’t attach the event to the button.
What’s crazy is that I can use the same exact code in useEffect, and it attaches the event listener to the custom button just fine.
I verified that the event listener is not attached by looking in the web console at events attached to the element after the page loaded.
You can easily reproduce this problem by placing this ponent somewhere in an app (and importing jquery with the emoji-area plugin):
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-ment-input' />
<i id={'emoji-btn' + props.blurtId} className='fa fa-smile emoji-btn' />
</>
)
}
Simply change this to a class ponent, and you’ll see that within ponentDidMount, everything works except the custom button. Any idea what could cause this change in behavior??
Here is the react class ponent version:
import React, {Component} from 'react';
class CommentInput extends Component {
constructor(props) {
super(props);
}
ponentDidMount() {
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-ment-input' />
<i id={'emoji-btn' + this.props.blurtId} className='fa fa-smile emoji-btn' />
</>
)
}
}
export default CommentInput;
Share
Improve this question
edited Aug 28, 2019 at 17:12
silencedogood
asked Aug 28, 2019 at 17:03
silencedogoodsilencedogood
3,2991 gold badge15 silver badges38 bronze badges
7
-
Since the code you're having trouble with is with a
class
ponent, we can't really help you if you don't show us that code. – T.J. Crowder Commented Aug 28, 2019 at 17:05 -
Please update your question with a minimal reproducible example demonstrating the problem, ideally a runnable one using Stack Snippets (the
[<>]
toolbar button). Stack Snippets support React, including JSX; here's how to do one. – T.J. Crowder Commented Aug 28, 2019 at 17:06 - @T.J.Crowder It's literally the same exact code.. Just changed to a react class ponent.. And EVERYTHING works in the class except this button. However, I'll add the class ponent version even though I think it's a bit much. – silencedogood Commented Aug 28, 2019 at 17:07
- 2 It isn't. :-) Remember, you're asking people to take time out of their day to help you. You want to make that as easy as possible. Thanks in advance for adding it, and as a runnable example. – T.J. Crowder Commented Aug 28, 2019 at 17:08
- 1 @T.J.Crowder Ahhh, very cool. This will e in handy. Thanks! – silencedogood Commented Aug 28, 2019 at 17:19
2 Answers
Reset to default 5There is a difference between when ponentDidMount
and useEffect
fires.
From the useEffect docs :
Unlike ponentDidMount and ponentDidUpdate, the function passed to useEffect fires after layout and paint
The big difference between ponentDidMount
and useEffect
is that useEffect
is run after every render, not just the first one. Since your render
outputs a new element on each render, after the first render the DOM element you attached the emoji thing to doesn't exist anymore, and a new one with the same ID does.
Options:
- Use
ponentDidUpdate
to handle the subsequent renders. (You'll still needponentDidMount
for the first one.) - Use a callback ref.
I’m stuck using a jquery emoji plugin on one of my ponents until I finish with a custom plugin I’m building.
For some reason, when I call the emoji plugin inside of ponentDidMount, everything works except the ability to utilize a custom button to show the emoji modal. When I use a custom button, the emoji plugin doesn’t attach the event to the button.
What’s crazy is that I can use the same exact code in useEffect, and it attaches the event listener to the custom button just fine.
I verified that the event listener is not attached by looking in the web console at events attached to the element after the page loaded.
You can easily reproduce this problem by placing this ponent somewhere in an app (and importing jquery with the emoji-area plugin):
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-ment-input' />
<i id={'emoji-btn' + props.blurtId} className='fa fa-smile emoji-btn' />
</>
)
}
Simply change this to a class ponent, and you’ll see that within ponentDidMount, everything works except the custom button. Any idea what could cause this change in behavior??
Here is the react class ponent version:
import React, {Component} from 'react';
class CommentInput extends Component {
constructor(props) {
super(props);
}
ponentDidMount() {
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-ment-input' />
<i id={'emoji-btn' + this.props.blurtId} className='fa fa-smile emoji-btn' />
</>
)
}
}
export default CommentInput;
I’m stuck using a jquery emoji plugin on one of my ponents until I finish with a custom plugin I’m building.
For some reason, when I call the emoji plugin inside of ponentDidMount, everything works except the ability to utilize a custom button to show the emoji modal. When I use a custom button, the emoji plugin doesn’t attach the event to the button.
What’s crazy is that I can use the same exact code in useEffect, and it attaches the event listener to the custom button just fine.
I verified that the event listener is not attached by looking in the web console at events attached to the element after the page loaded.
You can easily reproduce this problem by placing this ponent somewhere in an app (and importing jquery with the emoji-area plugin):
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-ment-input' />
<i id={'emoji-btn' + props.blurtId} className='fa fa-smile emoji-btn' />
</>
)
}
Simply change this to a class ponent, and you’ll see that within ponentDidMount, everything works except the custom button. Any idea what could cause this change in behavior??
Here is the react class ponent version:
import React, {Component} from 'react';
class CommentInput extends Component {
constructor(props) {
super(props);
}
ponentDidMount() {
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-ment-input' />
<i id={'emoji-btn' + this.props.blurtId} className='fa fa-smile emoji-btn' />
</>
)
}
}
export default CommentInput;
Share
Improve this question
edited Aug 28, 2019 at 17:12
silencedogood
asked Aug 28, 2019 at 17:03
silencedogoodsilencedogood
3,2991 gold badge15 silver badges38 bronze badges
7
-
Since the code you're having trouble with is with a
class
ponent, we can't really help you if you don't show us that code. – T.J. Crowder Commented Aug 28, 2019 at 17:05 -
Please update your question with a minimal reproducible example demonstrating the problem, ideally a runnable one using Stack Snippets (the
[<>]
toolbar button). Stack Snippets support React, including JSX; here's how to do one. – T.J. Crowder Commented Aug 28, 2019 at 17:06 - @T.J.Crowder It's literally the same exact code.. Just changed to a react class ponent.. And EVERYTHING works in the class except this button. However, I'll add the class ponent version even though I think it's a bit much. – silencedogood Commented Aug 28, 2019 at 17:07
- 2 It isn't. :-) Remember, you're asking people to take time out of their day to help you. You want to make that as easy as possible. Thanks in advance for adding it, and as a runnable example. – T.J. Crowder Commented Aug 28, 2019 at 17:08
- 1 @T.J.Crowder Ahhh, very cool. This will e in handy. Thanks! – silencedogood Commented Aug 28, 2019 at 17:19
2 Answers
Reset to default 5There is a difference between when ponentDidMount
and useEffect
fires.
From the useEffect docs :
Unlike ponentDidMount and ponentDidUpdate, the function passed to useEffect fires after layout and paint
The big difference between ponentDidMount
and useEffect
is that useEffect
is run after every render, not just the first one. Since your render
outputs a new element on each render, after the first render the DOM element you attached the emoji thing to doesn't exist anymore, and a new one with the same ID does.
Options:
- Use
ponentDidUpdate
to handle the subsequent renders. (You'll still needponentDidMount
for the first one.) - Use a callback ref.
本文标签:
版权声明:本文标题:javascript - different behavior with componentDidMount than useEffect when using jquery emoji plugin - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745543362a2155283.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论