React Hover to display information but hidden before hover - reactjs

This is my code so far
class PortfolioList extends Component{
render(){
const {column , styevariation } = this.props;
const list = PortfolioListContent.slice(0 , this.props.item);
return(
<React.Fragment>
{list.map((value , index) => (
<div className={`${column}`} key={index}>
<div className={`portfolio ${styevariation}`}>
<div className="thumbnail-inner">
<div className={`thumbnail ${value.image}`}></div>
<div className={`bg-blr-image ${value.image}`}></div>
</div>
<div className="content" >
<div className="inner">
<h3>{value.category}</h3>
<p>{value.title}</p>
<div className="portfolio-button">
<a className="rn-btn" href="/portfolio-details">Live</a>
</div>
<div className="portfolio-button">
<a className="rn-btn" href="/portfolio-details">GitHub</a>
</div>
</div>
</div>
</div>
</div>
))}
</React.Fragment>
)
}
}
This is displaying my portfolio section of my website I want to display the title of the each application and details only when i want to hover.
Also How can i make my buttons wrap next to each other? instead of taking up the new line?
Thank you

You can use onMouseEnter and onMouseLeave event to handle hovering. Bind a function to this event on title and keep a local boolean state shouldShowDetails with default value false. When the function is called, change this boolean to true and conditionally render the details.
For the second part, make your buttons container a flex and set flex-wrap to wrap.

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.

aligning 3 items next to each others using bootstrap react

so basically i have these photos:
i have created a postItem component which is just the structure of the image and i'm calling it from the api.js component from data using .map
the problem is, i used bootstrap grid system and used row and col-lg-4 to display each 3 on one line but its not working.
postItem.js:
import React from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
function PostItem ({src,thumbnailUrl,onClick,title}) {
return (
<div className="container-fluid text-center">
<div className="row">
<div className="col-lg-4">
<img src={src} onClick={onClick} alt="small post"></img>
<div>{title}</div>
</div>
</div>
</div>
)}
export default PostItem;
api.js:
<div>
<div>{newPhotosLocally.map(picture =>
<PostItem
key={picture.id}
src={picture.thumbnailUrl}
thumbnailUrl={picture.thumbnailUrl}
onClick={() => showPicture(picture.url,picture.id,picture.title)}
title={picture.title}/>
)}</div>
</div>
hope you can help me guys i've been stuck on this for an entire day
you have to do something like this
<div className="col-lg-4 d-flex">
{newPhotosLocally.map(picture =>
<PostItem
key={picture.id}
src={picture.thumbnailUrl}
thumbnailUrl={picture.thumbnailUrl}
onClick={() => showPicture(picture.url, picture.id, picture.title)}
title={picture.title} />
)}
</div>
because the reason is everytime iterate loop thus it will every time create new row . this is the reason you didn't get your images not align even we added display flex property ..
now remove unnecessary code from image portion .
hope you'll get it .

component is unmounted and constructor is called when rendering it in a different place in the DOM

I am trying to implement a minimize/maximize feature in React. I have a div that serves as an information panel and by clicking on a button I would like it to toggle between maximized / minimized states. My top level app component has a boolean state field (maximizedInfo in the example below) that tracks whether the information panel is maximized or not and accordingly renders either just the panel or the full grid of my application with many other DOM elements. The below code is obviously a minified example but the main idea is that the render() method of my top-level component generates two very different DOM trees depending on the state. Unfortunately, I have discovered that my information panel component keeps getting unmounted and the constructor is called on every state change, thus losing the state the information panel component had accumulated.
What is the proper way to address that and implement this sort of functionality in React?
const React = require('react');
class InformationPanel extends React.Component {
constructor(props) {
console.log('InformationPanel:: constructor'); // this keeps getting called
super(props);
}
render() {
return (
<div>
<a id='information' class='nav-link' href="#" onClick={this.props.toggleInfoPanel}>toggle</a>
short info
</div>
);
}
}
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
maximizedInfo: false
};
this.toggleInfoPanel = this.toggleInfoPanel.bind(this);
}
toggleInfoPanel() {
this.setState({maximizedInfo: !this.state.maximizedInfo});
}
render() {
if (this.state.maximizedInfo)
return (
<div class='container-fluid'>
<div class='row no-gutters'>
<div class='col-12 padding-0'>
<InformationPanel toggleInfoPanel={this.toggleInfoPanel}/>
</div>
</div>
</div>
)
else return (
<div class='container-fluid'>
<div class='row no-gutters'>
<div class='col-10'>
some other info that takes up more space ...
</div>
<div class='col-2 padding-0'>
<InformationPanel toggleInfoPanel={this.toggleInfoPanel}/>
</div>
</div>
</div>
);
}
}
1st of all - keep structure/tree unmodified [and more maintainable]:
render() {
return (
<div class='container-fluid'>
<div class='row no-gutters'>
{this.state.maximizedInfo &&
<div class='col-10'>
some other info that takes up more space ...
</div>
}
<div key="infoPanel" class='col-2 padding-0'>
<InformationPanel toggleInfoPanel={this.toggleInfoPanel}/>
</div>
</div>
</div>
);
}
Adding key prop helps in reconcilation - article
After this change <InformationPanel/> should not be rerendered. Notice that change is on parent - the place where child nodes differs. Parent not changed, props not changed, no rerendering.
2nd - above is not enough - we want size change!
I'd say that's a 'structural problem' - styling should be done inside <InformationPanel/> with required change passed as prop (f.e.):
<InformationPanel key="infoPanel" wide={!this.state.maximizedInfo} toggleInfoPanel={this.toggleInfoPanel}/>
// and in render in <InformationPanel/>
<div className={`padding-0 ${this.props.wide ? 'col-12' : 'col-2'}`}>
...
Still use key prop!
Other options for conditional styling in this thread
xadm's answer was correct that key is essential for tree reconciliation. The thing is, I discovered that the key needs to be present in the parent components, not necessarily in the InformationPanel component. The below code works:
if (this.state.maximizedInfo)
return (
<div key='a' class='container-fluid'>
<div key='b' class='row no-gutters'>
<div key='c' class='col-12 padding-0'>
{informationPanel}
</div>
</div>
</div>
)
else return (
<div key='a' class='container-fluid'>
<div key='b' class='row no-gutters'>
<div class='col-10'>
some other info that takes up more space ...
</div>
<div key='c' class='col-2 padding-0'>
{informationPanel}
</div>
</div>
</div>
);
Since you don't want to lose state in InformationPanel, you can declare it outside conditional rendering so that it won't be getting unmounted on state change. Code will look something like below:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
maximizedInfo: false
};
this.toggleInfoPanel = this.toggleInfoPanel.bind(this);
}
toggleInfoPanel() {
this.setState({maximizedInfo: !this.state.maximizedInfo});
}
render() {
const informationPanel = <InformationPanel toggleInfoPanel={this.toggleInfoPanel} />
if (this.state.maximizedInfo)
return (
<div class='container-fluid'>
<div class='row no-gutters'>
<div class='col-12 padding-0'>
{informationPanel}
</div>
</div>
</div>
)
else return (
<div class='container-fluid'>
<div class='row no-gutters'>
<div class='col-10'>
some other info that takes up more space ...
</div>
<div class='col-2 padding-0'>
{informationPanel}
</div>
</div>
</div>
);
}
}

How do you change content of page when the link is inside of the component?

Sorry in advance if I seem confused, it's because I am.
So from my App.js file which is like the main file where I call all my components and query my DB, which is then called by the index.js file.
this is my render method.
render() {
return (
<div className="site" >
{
!!!this.state.done ? (
<LoadingSVG />
) : (
<div className="page">
<div className="header-wrapper">
<Header data={this.state.dataHeader} />
</div>
<div className="project-list-wrapper">
<ProjectList data={this.state.dataProjects} />
</div>
</div>
)
}
</div >
)
}
Inside the Projectlist component I loop through every items and create a project.
render() {
return (
<div className="project-list module">
<div className="sectionTitle">Project I've worked on</div>
{this.props.data.map((res, i) => (
<div className="project-wrapper">
<div className="inner-ctn">
<div className="header">
<div className="number">0{res.id + 1}</div>
<div className="name">{res.nomProjet}</div>
</div>
<div className="item-ctn">
<div className="categ">{res.categProjet}</div>
<div className="roles">{res.roles}</div>
<div className="date">{res.date}</div>
</div>
</div>
</div>
))
}
</div>
);
}
What I want to do is with the use of transition-groups, render another component.. let's call it Project-1. Project 1 would refresh my App.js content so that the new component would render. But I can't do that since App.js is parent to ProjectList. I also want to keep a well structure project so I don't want to put everything in a single file..
I tried reading the documentation and basically every article about how to do this, I can't seem to wrap my mind around how this should work. This should be easy stuff, yet it's weirdly complicated to have a transition or even a link between two pages..

React & Bootstrap 4 Collapse

I'm importing:
import Collapse from "react-bootstrap/es/Collapse";
So i'm trying to get my collapse to work in my project here is from the render:
<div className="card-header" >
<a className="card-link" href='#compSci' onClick={this.toggleCollapse}>
Computer Sciences
</a>
</div>
<Collapse id="collapse1" isOpen = {this.state.collapse1}>
<div className="card-body">
<div className="row">
{
computerScience.map(skill => (
<div className="col">
<SkillPopover skill={skill} />
</div>
))
}
</div>
</div>
</Collapse>
With a toggle collapse function which changes the values from true to false
toggleCollapse = () => {
this.setState({ collapse1: !this.state.collapse1 });
console.log(this.state.collapse1)
}
I'm not quite sure what is going on with this as checking with the debugger it clearly changes the values of the state value collapse 1 between the true and false but it refused to open the Collapse. Any help would be greatly appreciated.
EDIT I'm following a guide here: https://reactstrap.github.io/components/collapse/
So my difficulty was that I failed to import the correct bootstrap. This is a reactstrap component and not a react-bootstrap component.

Resources