I have an instagram widget thas uses iframe, but when I switch between routes, the widget loads too slow and does'nt have time to render properly.
Can You tell me, how to set delay rendering of the component, jr another solution to this problem?
Here is the component:
import React, { Component } from 'react';
const divStyle = [
{
border: 'none',
overflow: 'hidden',
width: '100%'
},
{
font: "10px/14px 'Roboto','Helvetica Neue',Arial,Helvetica,sans-serif",
fontWeight: '400',
width: '100%',
textAlign: 'right'
},
{
color: '#777',
textDecoration: 'none'
}
];
class Instagram extends Component {
render() {
return (
<div id="instagram">
<iframe src="https://snapwidget.com/embed/711808" className="snapwidget-widget" allowtransparency="true" frameborder="0" scrolling="no" style={divStyle[0]}></iframe>
</div>
);
}
}
export default Instagram;
Also the code is located in the CodeSandbox.
Thanks for any help!
This can be possible solution from your code sandbox.
NOTE: Please Replace your loader with loading div.
CodeSandbox: https://codesandbox.io/s/damp-platform-950yw
import React, { Component } from "react";
const divStyle = [
{
border: "none",
overflow: "hidden",
width: "100%"
},
{
font: "10px/14px 'Roboto','Helvetica Neue',Arial,Helvetica,sans-serif",
fontWeight: "400",
width: "100%",
textAlign: "right"
},
{
color: "#777",
textDecoration: "none"
}
];
class Instagram extends Component {
state = {
loading: true
}
handelOnLoad = () => {
this.setState({
loading: false
})
}
render() {
return (
<>
{this.state.loading && <div style={{
position: "fixed",
background: "rgba(0,0,0,0.7)",
top: 0,
bottom: 0,
right: 0,
left: 0,
color: "#fff"
}}>Loading</div>}
<div id="instagram">
<iframe
src="https://snapwidget.com/embed/711808"
className="snapwidget-widget"
allowtransparency="true"
frameborder="0"
scrolling="no"
style={divStyle[0]}
onLoad={this.handelOnLoad}
/>
</div>
</>
);
}
}
export default Instagram;
You can make use of state to render,
class Instagram extends Component {
state={
show: false
}
componentDidMount(){
setTimeout(()=>{
this.setState({show: true})
},5000) //runs after 5sec
}
render() {
return (
<div id="instagram">
{ this.state.show && <iframe src="https://snapwidget.com/embed/711808" className="snapwidget-widget" allowtransparency="true" frameborder="0" scrolling="no" style={divStyle[0]}></iframe> }
</div>
);
}
}
Related
i have react carousel in the functional component , i am trying to change that component in to class component.. can any one help on this..
this is the link of code sand box....https://codesandbox.io/s/suspicious-cookies-fvm80?file=/src/App.js
functional component
import React, { useState } from 'react';
import ItemsCarousel from 'react-items-carousel';
export default () => {
const [activeItemIndex, setActiveItemIndex] = useState(0);
const chevronWidth = 40;
return (
<div style={{ padding: `0 ${chevronWidth}px` }}>
<ItemsCarousel
requestToChangeActive={setActiveItemIndex}
activeItemIndex={activeItemIndex}
numberOfCards={2}
gutter={20}
leftChevron={<button>{'<'}</button>}
rightChevron={<button>{'>'}</button>}
outsideChevron
chevronWidth={chevronWidth}
>
<div style={{ height: 200, background: '#EEE' }}>First card</div>
<div style={{ height: 200, background: '#EEE' }}>Second card</div>
<div style={{ height: 200, background: '#EEE' }}>Third card</div>
<div style={{ height: 200, background: '#EEE' }}>Fourth card</div>
</ItemsCarousel>
</div>
);
};
Wrap jsx in render() method, change useState hook to destruct from this.state, and create function for setting state.
Example
export default class carousel extends Component {
constructor(props) {
super();
this.state = {
activeItemIndex:0
};
}
setActiveItemIndex = (value) => {
this.setState({ activeItemIndex: value });
}
render() {
const { activeItemIndex } = this.state;
const chevronWidth = 40;
return (
<div style={{ padding: `0 ${chevronWidth}px` }}>
<ItemsCarousel
requestToChangeActive={this.setActiveItemIndex}
activeItemIndex={activeItemIndex}
numberOfCards={2}
gutter={20}
leftChevron={<button>{"<"}</button>}
rightChevron={<button>{">"}</button>}
outsideChevron
chevronWidth={chevronWidth}
>
<div style={{ height: 200, background: "#EEE" }}>First card</div>
<div style={{ height: 200, background: "#EEE" }}>Second card</div>
<div style={{ height: 200, background: "#EEE" }}>Third card</div>
<div style={{ height: 200, background: "#EEE" }}>Fourth card</div>
</ItemsCarousel>
</div>
);
}
}
New to react and trying to use in a new electron learning project I have. I'm trying to build a really basic drawing app.
I created a ToolbarButton class. That would represent each button and a Toolbar that would manage the button group. Example If you pick a 'primary' tool then it should turn off all other primary tools and leave only your current selection.
In jQuery I'd just do something like
let button = $(this);
let toolbar = $(this).parent();
toolbar.find('button.toolbar-button').removeClass('active');
button.addClass('active');
How would I do the same in react? I can toggle what I want to with setState from within the ToggleButton but separating it out into a prop seems to be an answer, but then I need to have the Toolbar manage the button 'active' states and I'm not sure how to do that. Think the answer is in ReactDOM, super newbie to react so apologize if the answer is overly obvious.
import React from 'react';
import FontAwesome from 'react-fontawesome';
import { ButtonGroup } from 'react-bootstrap';
import { ChromePicker} from 'react-color';
class ToolbarButton extends React.Component
{
state =
{
active: false
}
handleClick = ()=> {
if(this.props.onClick)
{
this.props.onClick();
}
this.setState({ active: !this.state.active});
}
render(){
return <div className={`btn btn-primary${this.state.active ? ' active' : ''}`} onClick={this.handleClick}>{this.props.children}</div>
}
}
class ColorPickerButton extends React.Component
{
constructor(props)
{
super(props);
this.state = {
displayColorPicker: false,
color: { r: 255, g: 255, b: 255, a:1 }
}
}
state = {
flyout: 'bottom',
displayColorPicker: false,
color: { r: 255, g: 255, b: 255, a:1 }
}
/* This button should have an option to display how the colorpicker flys out */
static flyoutStyles =
{
normal: { },
top: {top: '0px' },
bottom: { top: '100%' },
left: { right: '100%' },
right: { left: '100%' }
}
handleClick = (e) => {
this.setState({ displayColorPicker: !this.state.displayColorPicker});
}
handleClose = () => {
this.setState({ displayColorPicker: false });
}
handleChange = (color) => {
this.setState({ color: color.rgb });
}
stopPropagation = (e) => {
e.stopPropagation();
}
render()
{
const swatchStyle = {
backgroundColor: `rgba(${this.state.color.r},
${this.state.color.g},
${this.state.color.b},
${this.state.color.a})`,
height: '16px',
width: '16px',
border: '1px solid white'
};
const popup = {
position: 'absolute',
zIndex: 2,
top: 'calc(100% + 2px)'
};
const cover = {
position: 'fixed',
top: '0px',
right: '0px',
left: '0px',
bottom: '0px',
};
return (
<ToolbarButton onClick={this.handleClick} active={this.state.displayColorPicker}>
<div style={swatchStyle} />
{
this.state.displayColorPicker ?
<div style={popup} onClick={this.stopPropagation}>
<div style={ cover } onClick={ this.handleClose }/>
<ChromePicker color={this.state.color} onChange={this.handleChange} />
</div>
: null
}
</ToolbarButton>
);
}
}
export class CanvasToolbar extends React.Component
{
handleClick = (e) => {
}
render(){
return (<div className="CanvasToolbar">
<ButtonGroup vertical>
<ToolbarButton>
<FontAwesome name='paint-brush' />
</ToolbarButton>
<ToolbarButton>
<FontAwesome name='eraser' />
</ToolbarButton>
<ToolbarButton>
<FontAwesome name='magic' />
</ToolbarButton>
<ColorPickerButton />
</ButtonGroup>
</div>);
}
}
I'm creating a React widget and using the react-jss HOC for styling. The widget is just a small part of a larger page, and I want to be able to signal it to open or close with a button on another part of the page outside of the React render. Originally I was doing it like this:
var modal = ReactDOM.render(<Modal />, document.getElementById('widget'))
// Inside an onClick function
modal.toggleModal()
That was before JSS, but now widget doesn't return the component, it returns the JSS HOC. I've tried passing <Widget /> a prop and updating that and then using widget.forceUpdate() but that did nothing. Not really sure what else to try at this point. I'm currently just toggling everything outside of React, but I want the component to be able to close itself as well.
import React, { Component } from 'react'
import injectSheet from 'react-jss'
const styles = {
show: {
display: 'block',
},
modal: {
display: 'none',
background: 'rgba(0, 0, 0, 0.3)',
position: 'fixed',
top: 0,
left: 0,
bottom: 0,
right: 0,
width: '100%',
height: '100%',
},
form: {
maxWidth: '440px',
margin: '15px',
padding: '30px',
background: '#fff',
position: 'fixed',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)'
},
input: {
width: '100%',
marginBottom: '15px'
},
button: {
width: '100%'
}
}
class Modal extends Component {
constructor(props) {
super(props)
this.state = {
show: false
}
this.toggleModal = this.toggleModal.bind(this)
}
toggleModal() {
this.setState({show: !this.state.show})
}
render() {
const { classes } = this.props
return (
<div className={`${classes.modal} ${this.state.show ? classes.show : ''}`}>
<form className={classes.form}>
<label htmlFor="aatitle-field">Title</label>
<input className={classes.input} type="text" id="aatitle-field" name="title" value="" />
<button className={`btn ${classes.button}`}>Save</button>
</form>
</div>
)
}
}
export default injectSheet(styles)(Modal)
First of all, please use the classnames library to generate classNames, it's so more elegant.
Secondly, classes are applied in order they are parsed by the brower. So what you're doing is tricky. How can we know if the modal class is parsed before show? (This is a requirement in your current code). You can simply move the modal declaration before the show declaration in styles and surely this will work, but this is a fragile solution. Better is to use a show and hide class and apply them according the state. This removes the dependency of which style class is loaded first. So remove display:none from modal and introduce hide:
Something like:
import React, { Component } from 'react'
import injectSheet from 'react-jss'
const styles = {
show: {
display: 'block',
},
hide: {
display: 'none',
},
modal: {
background: 'rgba(0, 0, 0, 0.3)',
position: 'fixed',
top: 0,
left: 0,
bottom: 0,
right: 0,
width: '100%',
height: '100%',
},
form: {
maxWidth: '440px',
margin: '15px',
padding: '30px',
background: '#fff',
position: 'fixed',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)'
},
input: {
width: '100%',
marginBottom: '15px'
},
button: {
width: '100%'
}
}
class Modal extends Component {
constructor(props) {
super(props)
this.state = {
show: false
}
this.toggleModal = this.toggleModal.bind(this)
}
toggleModal() {
this.setState({show: !this.state.show})
}
render() {
const { classes } = this.props
return (
<div className={`${classes.modal} ${this.state.show ? classes.show : classes.hide}`}>
<form className={classes.form}>
<label htmlFor="aatitle-field">Title</label>
<input className={classes.input} type="text" id="aatitle-field" name="title" value="" />
<button className={`btn ${classes.button}`}>Save</button>
</form>
</div>
)
}
}
export default injectSheet(styles)(Modal)
```
I am trying React MobX on hover over a list item. Here is my code
export default observer(
class SidebarContent extends React.Component {
constructor(props) {
super(props);
}
componentWillMount() {
this.props.store.fetchSources()
}
toggleHover(){
this.props.store.hover = !this.props.store.hover;
}
getArticles(src) {
this.props.store.fetchArticles(src);
}
render() {
const style1 = this.props.style ? {...styles.sidebar, ...this.props.style} : styles.sidebar;
const { sources, hover } = this.props.store
var linkStyle;
if (this.props.store.hover) {
linkStyle = {backgroundColor: 'black'}
} else {
linkStyle = {backgroundColor: 'white'}
}
const links = sources.map( (src,index) => (
<a key={index} href='javascript:;' style={styles.sidebarLink} onClick={this.getArticles.bind(this, src.id)} >
<span style={linkStyle} onMouseEnter={this.toggleHover.bind(this)} onMouseLeave={this.toggleHover.bind(this)} >
<img className="ui-avaatar image" src='{ src.urlsToLogos.small }' />
<span className="side-news-item"> {src.name} </span>
</span>
</a>
))
return (
<MaterialTitlePanel title="Menu" style={style1}>
<div style={styles.content}>
<div style={styles.divider} />
{links}
</div>
</MaterialTitlePanel>
);
}
}
);
const styles = {
sidebar: {
width: 256,
height: '100%',
},
sidebarLink: {
display: 'block',
padding: '16px 0px',
color: '#757575',
textDecoration: 'none',
},
divider: {
margin: '8px 0',
height: 1,
backgroundColor: '#757575',
},
content: {
padding: '16px',
height: '100%',
backgroundColor: 'white',
},
};
this.props.store.hover is a observable.
The problem is that when mouse over one item, all of the items get the hover effect. What did I do wrong?
Do not set Component's props directly, set it on upper Component.
or you could use state feature, and always use setState() to change state.
write an subcomponent to control the Button State
code below maybe help
class SidebarContent extends React.Component {
constructor(props) {
super(props);
}
componentWillMount() {
this.props.store.fetchSources()
}
getArticles(src) {
this.props.store.fetchArticles(src);
}
render() {
const links = sources.map( (src,index) => <Button />);
return (
<MaterialTitlePanel title="Menu" style={style1}>
<div style={styles.content}>
<div style={styles.divider} />
{links}
</div>
</MaterialTitlePanel>
);
}
}
class Button extends React.Component {
toggleHover(){
this.setState({
hover: !this.state.hover,
});
}
render() {
const style1 = this.props.style ? {...styles.sidebar, ...this.props.style} : styles.sidebar;
const { sources } = this.props.store
const { hover } = this.state;
var linkStyle;
if (hover) {
linkStyle = {backgroundColor: 'black'}
} else {
linkStyle = {backgroundColor: 'white'}
}
return (
<a key={index} href='javascript:;' style={styles.sidebarLink} onClick={this.getArticles.bind(this, src.id)} >
<span style={linkStyle} onMouseEnter={this.toggleHover.bind(this)} onMouseLeave={this.toggleHover.bind(this)} >
<img className="ui-avaatar image" src='{ src.urlsToLogos.small }' />
<span className="side-news-item"> {src.name} </span>
</span>
</a>
);
}
}
const styles = {
sidebar: {
width: 256,
height: '100%',
},
sidebarLink: {
display: 'block',
padding: '16px 0px',
color: '#757575',
textDecoration: 'none',
},
divider: {
margin: '8px 0',
height: 1,
backgroundColor: '#757575',
},
content: {
padding: '16px',
height: '100%',
backgroundColor: 'white',
},
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
I'm using burger-menu and i can't set CSS for the burger menu like the author guide: https://github.com/negomi/react-burger-menu
Here's my burger menu component:
import React from 'react';
import BurgerMenu from 'react-burger-menu';
import { List, ListItem, ListItemContent } from 'react-mdl';
var MenuWrap = React.createClass({
getInitialState() {
return {hidden : false};
},
toggle() {
this.setState({hidden: !this.state.hidden});
},
render() {
let style;
if (this.state.hidden) {
style = {display: 'none'};
}
return (
<div style={style} className={this.props.side}>
{this.props.children}
</div>
);
}
});
export default class LeftSidebar extends React.Component {
constructor(props) {
super(props);
this.state = {
currentMenu: 'push',
side: 'left',
hidden: true,
};
};
render() {
const Menu = BurgerMenu[this.state.currentMenu];
var styles = {
bmBurgerButton: {
position: 'fixed',
width: '36px',
height: '30px',
left: '36px',
top: '36px'
},
bmBurgerBars: {
background: '#373a47'
},
bmCrossButton: {
height: '24px',
width: '24px'
},
bmCross: {
background: '#bdc3c7'
},
bmMenu: {
background: '#373a47',
padding: '2.5em 1.5em 0',
fontSize: '1.15em'
},
bmMorphShape: {
fill: '#373a47'
},
bmItemList: {
color: '#b8b7ad',
padding: '0.8em'
},
bmOverlay: {
background: 'rgba(0, 0, 0, 0.3)'
}
};
return (
<MenuWrap wait={20}>
<Menu
style={styles}
noOverlay id={this.state.currentMenu}
pageWrapId={'page-wrap'}
outerContainerId={'outer-container'}
>
{console.log(Menu)}
<List>
<ListItem>
<ListItemContent icon="person">Dashboard</ListItemContent>
</ListItem>
<ListItem>
<ListItemContent icon="person">Community</ListItemContent>
</ListItem>
<ListItem>
<ListItemContent icon="person">About</ListItemContent>
</ListItem>
</List>
</Menu>
</MenuWrap>
);
}
};
And here is my main component:
import React from 'react';
import styles from './Main.scss';
import LeftSidebar from '../LeftSidebar/LeftSidebar'
export default class Program extends React.Component {
render() {
return (
<div id="outer-container" style={{height: '100%'}}>
<LeftSidebar />
<div id="page-wrap">
<p>Content</p>
</div>
</div>
);
}
}
All of the css from variable styles does not work.
EDIT: the problem above is solved by change style ={styles} to styles = {styles}. The other problem is: when i click close, the sidebar menu shift down about 10 or 20px before moving back to the left. How to remove that shift down effect?
Seems like you have a typo. It should be styles={styles} instead of style={styles}.