Why react-frame-component iframe's body becomes empty? - reactjs

Imagine, rendering multiple iframes (using react-frame-component) and allowing users to reorder them.
Surprisingly, when iframes are reordered, the <body> of one of them becomes empty.
I raised an issue here, but wonder maybe someone here would be able to assist as well since there is no much activity on the repo lately.
function App() {
const [frames, setFrames] = useState(["first", "second"]);
return (
<div className="app">
<div className="framesContainer">
{frames.map(frame => (
<div className="frame" key={frame}>
<Frame style={{ width: 200, height: 200 }}>
<h1>Hello World</h1>
</Frame>
<div>{frame}</div>
</div>
))}
</div>
<div className="actions">
<button
onClick={() => {
setFrames(frames => [frames[1], frames[0]]);
}}
>
Swap frames
</button>
</div>
</div>
);
}
After clicking the button, first iframe's <body> becomes empty.
CodeSandbox

I face the same issue when using react-dnd / react-beautiful-dnd to do multiple iframe reordering and sorting.
The only method I found is to force the iframe component to rerender when the orders state update. However, the app could be extremely slow when all iframe update at once.

Related

UI Kit Icon Not Rendering on Load

I have a nextjs blog that I'm working on and one of the components I'm using is this card component:
function Card(props) {
return (
<div className="uk-card uk-card-default uk-width-1-2#m">
<div className="uk-card-header">
<div
className="uk-grid-small uk-flex-middle"
uk-grid
uk-scrollspy="cls: uk-animation-slide-left; repeat: true"
>
<div className="uk-width-auto">
<Image
alt="Profile Picture"
className="uk-border-circle"
src={props.pic}
height={200}
width={200}
/>
</div>
<div className="uk-width-expand">
<h3 className="uk-card-title uk-margin-remove-bottom">
{props.name}
</h3>
</div>
</div>
</div>
<div className="uk-card-body">
<p>{props.description}</p>
</div>
<div className="uk-card-footer">
</div>
</div>
)
}
I take that component and use it in the page like so:
export default Main =()=> {
return(
<Card
pic={placeholderpic}
linkedin='https://www.linkedin.com/'
name="Harry Truman"
description="Lorem ipsum"
/>
)
}
The icon in the footer does not render until the page is refreshed 3-4 times. All the rest of the card renders properly on first load. Ideally I'd like to know 3 things:
A. Why this is occurring?
B. How to troubleshoot this in the future?
C. What the most appropriate fix is for this.
Edit:
This question is essentially the same as mine:
Uikit Icons with React and Next.js
The solution for me is less than ideal, I don't want to wrap everything in a custom "UIKit" component.

How to NOT render/ hide a React component when no prop is passed?

TLDR: Cannot figure out why component is still being rendered while no props are passed.
So I have been building a NextJS application, and I have this banner component that is shown on every page of my website. It has some header text, buttons and an image:
const Banner = (props) => {
return (
<div className={bannerStyles.wrapper}>
<div className={classnames(bannerStyles.banner, "wrap", "center")}>
<div className={bannerStyles.banner_left}>
<h1>{props.header}</h1>
<div className={bannerStyles.button_wrapper}>
<div className={bannerStyles.button}>
<Button>{props.button || null}</Button>
</div>
<div className={bannerStyles.button}>
<Button>{props.scnd_button || null}</Button>
</div>
</div>
</div>
<div className={bannerStyles.banner_right}>
<Image src={props.image} alt=""></Image>
</div>
</div>
</div>
);
};
Inside of this, as you can see I have two Button components (The MDEast thing is an arrow icon):
const Button = ({children}) => {
return (
<div className={buttonStyles.button}>
<Link href="/"><a>{children} <MdEast /></a></Link>
</div>
)
}
Now I want the option that if no prop is passed, that the Button component(s) do(es) not render/ is hidden from the page, so that it is optional per page. Yet the Button does still render, even though I am not passing any props on my About page. My about page:
const About = () => {
return (
<>
<Banner
header="Hello this is my code"
image={banner_placeholder}
/>
</>
)
}
PS. I am fairly new to React and NextJS, so this might be a beginner mistake, or I am not understanding the fundamentals well enough, but could someone point me in the right direction please?
To conditionally render the button you can use:
props.button && <Button>{props.button}</Button>
When props.button is falsy, then button will not get rendered.

Too much blank space under each card, using reactjs-social-embed

I am making a webpage using react where I want to display every post in a facebook page. I am using this package to display each post and Facebook graph API to get each postID then I map it.
https://www.npmjs.com/package/reactjs-social-embed
My problem is that there is just too much blank space under each facebook post(See img). Id like each post to be positioned right on top of eachother.
If I try to change the height to auto or 100% the Like btn, comment, and share btn disappears.
return (
<>
{fbData.map((post) => (
<div style={{paddingTop: 40}}
className="col-lg-5 col-md-5 col-sm-5 container justify-content-center">
<Row>
<Facebook type="post"
width="800px"
height="680px"
url={`https://www.facebook.com/102417811874407/posts/${post.id.split("_")[1]}`} />
</Row>
</div>
)
)}
</>
);
};
export default Nyheter;
The facebook API does not return img size either :/
This is how it looks if I try to change each post to 200px

How do you do a map within a map through an array for only certain items?

So far the map is working perfectly except for one problem, every time I click the button to post a comment a whole new post populates the UI. What I want is to only render a comment not a whole post every time I click the post comment button. What I tried to do is do map within a map, as you can see below. However its still rendering the a whole post. How do I map for a certain item, I think that will help. What should I do?
const { TextArea } = Input;
const PostOnWall = (props) => (
<div>
{props.postInfo.map( (item) => (
<div>
<div className="PostOnWall">
<div className="topbar">
<img src = {profile} className="image"/>
<div className="name">Brad Pitt</div>
<div>{item.time}</div>
</div>
<div className="text">{item.post}</div>
<img src={item.uploadedImage} />
</div>
<div className="engagementBar">
<div><FontAwesomeIcon icon={fathumbsup} size="2x"/> Like</div>
<div><FontAwesomeIcon icon={facomment} size="2x"/> Comment</div>
<div><FontAwesomeIcon icon={fasharesquare} size="2x"/> Share</div>
</div>
<div className="postCommentBox">
<img src = {profile} className="image"/>
<TextArea type = "text" placeholder="Write a comment" autoSize id="comment" onChange={props.onChange}/>
<div>
<button onClick={props.onClick}></button>
</div>
</div>
{item.comment.map( (items) => (
<div>
<div> {items} </div>
</div>
))
}
</div>
))
}
</div>
)
I think with current structure it's not really possible to re-render only comments. In order to make that possible you might need to move comments to a separate component.
Another important thing I spot you don't use key while rendering lists, so it decreases performance quite a lot as React will need to re-render the whole list on each render. You can read about it here: https://reactjs.org/docs/lists-and-keys.html

Carousel in ReactJS using ReactAnimationGroup

I am trying to create a scrolling carousel, similar to bootstrap's carousel, using pure React and inline styles.
I'm having a lot of trouble figuring out how state should be.
Here is the relevant code:
Parent component:
customers.jsx
<button style={{zIndex: 100}} onClick={() => this.renderPrev()}>Prev</button>
<ReactTransitionGroup transitionName="example">
{_.map(customers, (customer, i) => {
if (this.state.selected === i){
return <Customer
key={customer.name}
customer={customer}
selected={this.state.selected}
idx={i}
moving={this.state.moving}
toggle={()=>this.toggle()}
/>
} else {
return null
}
})
}
</ReactTransitionGroup>
<button style={{zIndex: 100}} onClick={() => this.renderNext()}>Next</button>
renderPrev/renderNext are simply functions that checks to see if the current selected customer is the first or last one, and if it is, then loop around.
Child component
customer.jsx
render() {
<div style={_.assign({},styles.root, position)}>
<div style={{verticalAlign: 'middle'}} >
<img style={styles.image} className="img-circle img-responsive" width="200px" src={this.props.customer.image}/>
<img style={styles.logo} className="img-responsive" src={this.props.customer.logo}/>
<h3 style={{color: '#F05A28', margin: 0,}}>{this.props.customer.name}</h3>
<h4 style={{fontWeight: 200, margin: 0,}}>{this.props.customer.title}</h4>
<p style={{fontSize: 16}}>{this.props.customer.description}</p>
</div>
<button onClick={()=>this.props.toggle()}>Click</button>
</div>
}
I'm able to get carousel to work, but it's static. Ideally, I want the customers to slide left/right depending on if it's going to the next or previous customer.
My attempted solution was to try to send new props into the current customer when the next button is pressed, but the current customer never receives those new props because it's not even rendered due to the conditional.
I think the main problem is that only one customer is rendering at a time due to the condition within the map, and that customer does not get the index of the next customer.
Can someone guide me in the right direction?
I know there's React Slick Carousel but I wasn't able to get it to work, so I wanted to try my hand at doing it myself.

Resources