问题
I'm using ReactJS (developped by Facebook) and I'm currently having issues displaying a Comment secton from Facebook Social Plugins... kind of ironic but hey, they haven't made a plugins themselft for react.
Anyway, I have inserted the diffent element in my code to add the comment section. When I'm loading the page, I can see the section is loading! (for less than a second) but it desappear quite rapidly. I checked the code generated by facebook and I found that it was adding in the class of my element : FB_hide_iframes. I tried removing it and the section was showing in my page!
The problem is that I don't know how to control the class added to my component.
As you can see, the comments section is present, but it is hidden by the class FB_hide_iframes which i haven't put there.
Here's the code to add the section in my home page (home.js)
componentDidMount() {
...
window.fbAsyncInit = function () {
FB.init({
appId: 'XXXXXXXXXXXXXX',
xfbml: true,
version: 'v2.6'
});
};
(function (d, s, id) {
console.log('test');
const fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
const js = d.createElement(s); js.id = id;
js.src = '//connect.facebook.net/fr_CA/sdk.js#xfbml=1&version=v2.6&appId=XXXXXXXX';
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
FB.XFBML.parse();
...
}
and in the render function I added :
render() {
<div id="fb-root"></div>
...
<div className="fb-comments"
data-href="MY-URL"
data-width="1000"
data-numposts="10"
data-order-by="reverse_time">
</div>
Anyone got an idea?
Edit: The comments section is showing, but when I go in another section of my website and comeback (Single-page App), it Disappears. Here's the code of my component :
import React, { Component, PropTypes } from 'react';
import { mediaQueries } from '../../decorators';
@mediaQueries
export default class FacebookComments extends Component {
static propTypes = {
mediaQueries: PropTypes.func.isRequired,
appId: PropTypes.string.isRequired,
version: PropTypes.string.isRequired,
url: PropTypes.string.isRequired,
};
state = {
mobile: false,
}
componentDidMount() {
this.props.mediaQueries('(max-width: 950px)', () => {
this.setState({
mobile: true,
});
});
this.props.mediaQueries('(min-width: 951px)', () => {
this.setState({
mobile: false,
});
});
FB.init({
appId: 'XXXXXXXXXXXXXXXXX',
xfbml: true,
version: 'v2.6',
});
(function (d, s, id) {
const fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) return;
const js = d.createElement(s); js.id = id;
js.src = '//connect.facebook.net/fr_CA/sdk.js';
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
}
componentDidUpate() {
FB.XFBML.parse();
}
render() {
const componentWidth = this.state.mobile ? '95%' : '75%';
return (
<div style={{ width: componentWidth }}>
<div id="fb-root"></div>
<div className="fb-comments"
data-href={this.props.url}
data-width="100%"
data-numposts="10"
data-order-by="reverse_time">
</div>
</div>
);
}
}
luschn I don't know and don't understand what you are saying. I put a console.log in fbAsyncInit and it never showed, which mean it never get called. I looked online and there's no information about it. People online only say : Put that in you code and let the magic happen..... That's why I removed it from my code. Edit #2 : All I have for Facebook Social Plugin is in this code.
回答1:
Side Note: It is a terrible idea to add the JS SDK init code in componentDidMount
. Instead, add that code to your base HTML or put it in a separate "init" function and make sure it´s loaded before using the component.
Either way, you can only use FB.XFBML.parse
after FB.init
- that is, when the JS SDK is loaded and initialized:
FB.init({
appId: 'XXXXXXXXXXXXXX',
xfbml: true,
version: 'v2.6'
});
FB.XFBML.parse();
You should even have a warning or error in the browser onsole that FB is not defined with your current code.
You may also need to call FB.XFBML.parse()
again in componentDidUpdate
.
That being said, here´s my idea of it:
componentDidMount() {
window.fbAsyncInit = () => {
FB.init({
appId: 'xxx',
xfbml: true,
version: 'v2.6'
});
FB.XFBML.parse();
console.log('make sure this happens');
};
(function(d, s, id){
let js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {return;}
js = d.createElement(s); js.id = id;
js.src = '//connect.facebook.net/en_US/sdk.js';
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
}
componentDidUpdate() {
FB.XFBML.parse();
}
Again, you should put that init/loading stuff elsewhere, but that´s just for optimization. Check your browser console for errors, it may be possible that componentDidUpdate
gets called before the JS SDK is initialized. In that case, you may need to check if FB is available:
componentDidUpdate() {
if (FB) {
FB.XFBML.parse();
}
}
Alternatively, you could use a state variable ("isSDKInitialized", for example) and set it to true after FB.init:
componentDidUpdate() {
if (this.state.isSDKInitialized) {
FB.XFBML.parse();
}
}
That´s the minimum you need, the problem with routing is that both componentDidUpdate
and componentDidMount
will not get called. Try with componentWillReceiveProps
in addition (same code as in componentDidUpdate
to refresh the Social Plugins).
Check out those links for more information - assuming you are using react-router
:
- https://github.com/reactjs/react-router/issues/527
- https://github.com/reactjs/react-router/blob/master/docs/guides/ComponentLifecycle.md
回答2:
For those wondering how to correct the bug. You must NOT have : <script src="//connect.facebook.net/fr_CA/sdk.js"></script>
in your <head>
, you MUST have <div id="fb-root"></div>
at the beginning of the <body>
and this code in your FacebookComments Component :
componentDidMount() {
this.props.mediaQueries('(max-width: 950px)', () => {
this.setState({
mobile: true
});
});
this.props.mediaQueries('(min-width: 951px)', () => {
this.setState({
mobile: false
});
});
window.fbAsyncInit = () => {
FB.init({
appId: this.props.appId,
xfbml: true,
version: this.props.version,
});
FB.XFBML.parse();
};
(function (d, s, id) {
const fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {
return;
}
const js = d.createElement(s); js.id = id;
js.async = true;
js.src = '//connect.facebook.net/fr_CA/sdk.js';
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
}
componentWillReceiveProps() {
if (FB) {
console.log('its in receiveProps');
FB.XFBML.parse();
}
}
componentDidUpate() {
if (FB) {
FB.XFBML.parse();
}
}
This me code however is giving me one error, but it doesn't stop the webapp from loading the comments section. You propably will get a :
Unhandled promise rejection ReferenceError: FB is not defined(…)
I tried to make a flag with a element of the state, but it isnt the same state from before.
来源:https://stackoverflow.com/questions/37355637/facebook-social-plugins-comments-section-hidden-by-classname-reactjs