Content Go hidden on top in React - reactjs

I'm new to react. I am creating a cardlist with react bootstrap. Problem is no matter what I do When my list become larger it overflow and show like this.
Note that my other half is hidden on top of the browser.
my fragment of code is below.
class Admin extends Component {
render() {
const examlist = exams ? (
exams.map((exam) => {
let tempTime = new Date(exam.startTime.seconds * 1000);
let time = tempTime.toLocaleDateString("en-GB", {
hour: "numeric",
hour12: true,
});
return (
<AddExamTab
key={exam.id}
title={exam.title}
description={exam.description}
id={exam.id}
className={exam.class}
time={time}
/>
);
})
) : (
<div className="container">
<h4>
<Spinner />
</h4>
</div>
);
return (
<div className="container">
<AddExam />
{examlist}
</div>
);
}
}
Maybe I have done somthing silly. what am I doing wrong here? Can anyone tell me? I'd be very grateful if anyone help me in this problem.

It's not a React related problem, but a CSS related.
You should experiment with the parent div (with "container" class). Try to create your own class, add height and overflow properties.
Here is a small example of how you can implement that:
.container {
height: 200px;
width: 50%;
overflow-y: scroll;
background-color: #828282;
}
.container > div {
height: 100px;
margin-bottom: 2px;
background-color: #929292;
}
<div class="container">
<div>x1</div>
<div>x2</div>
<div>x3</div>
<div>x4</div>
<div>x5</div>
</div>

Related

React do I need a hook for each component?

Problem Description
I have faced this issue multiple times and am not sure what is the best approach. Say I have 3+ components how can I have a state tracker for each of them? Do I need n useState() hooks for n components?
In this example, I want to change the image displayed with onMouseOver(). The way I did it, the hook state is applied to all the images, which is not what I desire to do.
Restrictions
I want to have eventually a custom drop-down menu with onClick() particular to the image folder. So in that sense, I need an individual state tracker for each component?
Code and Snippet
const openFolder = "https://i.postimg.cc/V6L7kBCV/folder-Open.png";
const closedFolder = "https://i.postimg.cc/hG0yn3fm/folder-Closed.png"
function App() {
const [image, setImage] = React.useState(closedFolder);
const handleMouseOver = () => {
setImage(openFolder);
}
const handleMouseLeave = () => {
setImage(closedFolder);
}
return (
<div className="window">
<div className="slider">
<div className="container">
{buildLatexFolder(image,handleMouseOver,handleMouseLeave)}
</div>
</div>
</div>
);
}
const buildLatexFolder = (image,handleMouseOver,handleMouseLeave) => {
const courseNames = [
'A', 'B', 'C', 'D', 'E', 'F'
//and many more other
]
var folders = courseNames.map((value, index) => {
return (
<div className="folderContainer">
<span>{value}</span>
<div onMouseEnter={() => {handleMouseOver()}} onMouseLeave={() => {handleMouseLeave()}}>
<img src={image} width="130"/>
</div>
</div>
);
});
return folders;
}
ReactDOM.render(<App />, document.querySelector("#app"));
.window {
width: 500px;
height: 130px;
display: flex;
align-items: center;
margin-left: auto;
margin-right: auto;
}
.slider {
border-radius: 0px 0px 16px 16px;
background-color: #1F1F1F;
color: #ffffff;
overflow: hidden;
float: right;
}
.container {
display: flex;
width: 700px;
height: 130px;
margin-top: 10px;
align-items: center;
text-align: center;
}
.folderElement {
margin-left: 12px;
margin-right: 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="app"></div>
with JSFiddle here
What I Have Tried
Previously, when faced with this problem I would just make, say, 3 hooks for my 3 components and handle the logic this way. But now I have a large number of components and don't know what is the best approach.
I have searched online 'React Should I have a hook for each component', 'How many hooks to have for components', and so on and so forth but the search results are inaccurate with what I am trying to find, or for that matter my question is inaccurate. I don't know how to proceed.
Does anyone know how I can fix this issue?
You need to have component modularization in your application. Then you can have a single CourseFolder which can be used as a child component resides in your parent component which is App. Using map, you can view multiple child components having different courseDetails inside them.
Refer the following code-snippets I created to solve your issue.
App.js
import React from "react";
import CourseFolder from "./CourseFolder";
// import "./folderStyles.css"; /* kept the styles posted in the question */
const courseNames = [
"A",
"B",
"C",
"D",
"E",
"F",
//and many more other
];
function App() {
return (
<div className="window">
<div className="slider">
<div className="container">
{courseNames.map((value, index) => (
<CourseFolder value={value} key={index} />
))}
</div>
</div>
</div>
);
}
export default App;
Then create the child component as follows.
CourseFolder.js
import React from "react";
const openFolder = "https://i.postimg.cc/V6L7kBCV/folder-Open.png";
const closedFolder = "https://i.postimg.cc/hG0yn3fm/folder-Closed.png";
function CourseFolder(props) {
const { value, key } = props;
const [image, setImage] = React.useState(closedFolder);
const handleMouseOver = () => {
setImage(openFolder);
};
const handleMouseLeave = () => {
setImage(closedFolder);
};
return (
<div className="folderContainer" key={key}>
<span>{value}</span>
<div
onMouseEnter={() => {
handleMouseOver();
}}
onMouseLeave={() => {
handleMouseLeave();
}}
>
<img src={image} width="130" alt="alternative" />
</div>
</div>
);
}
export default CourseFolder;
Hope this would be helpful to solve your issue.

Conditional rendering + React

i tried making a method that holds the previous state, and changes back to the the previous state on click. Yet I checked if the method was working, and it was properly changing between true and false.
Yet, when I do a ternary operator in the className, it stays as the true value, and does not let me toggle between two classes. The first being the regular border, and the second having the position absolute with the checkmark to indicate it was selected. Even when I check dev tools, 'checkmark' is the className but nothing changes onClick...
import React from 'react';
import './Questions.css'
import girl_sweat from './girl_sweat.jpg'
class Questions extends React.Component {
constructor(props){
super(props);
this.state = {
isChoiceClicked: false
}
this.handleChoice = this.handleChoice.bind(this);
}
handleChoice(){
this.setState(prevState => ({isChoiceClicked: !prevState.isChoiceClicked}));
}
render(){
const isChoiceClicked = this.state;
return <div className="banner_column">
<div className="banner_column_1"><img src={girl_sweat}/></div>
<div className="banner_column_2"><div className="survey_enter"><h2 className="title">What are you interested in?</h2>
<p className="description">Select up to <strong>3 areas</strong></p>
<div className="choices">
<div className={`choice_container ${isChoiceClicked ? 'checkmark': 'null'}`} onChange={this.handleChoice}><h5>Yoga</h5><p className="activities">Vinyasa, Ashtanga, Kundalini, Hatha, Restorative, Prenatal</p></div>
<div className={`choice_container ${isChoiceClicked ? 'checkmark': 'choice_container'}`} onChange={this.handleChoice}><h5>Fitness</h5><p className="activities">Strength, Barre, Pilates, HIIT, Core, Stretching</p></div>
<div className={`choice_container ${isChoiceClicked ? 'checkmark': 'choice_container'}`} onChange={this.handleChoice}><h5>Mindfullness</h5><p className="activities">Meditation, Breathwork, Sound Bath, Yoga Nidra</p></div>
<div className={`choice_container ${isChoiceClicked ? 'checkmark': 'choice_container'}`} onChange={this.handleChoice}><h5>Skills</h5><p className="activities">Handstands, Arm Balances, Flexibility, Mobility</p></div>
</div>
<div className="next"><button className="next_question">next question</button></div>
</div>
</div>
</div>
}
}
export default Questions; ```
.choice_container {
margin: 0 auto;
width: 250px;
padding: 1rem;
border: solid 0.5px black;
position: relative;
}
.choice_container .checkmark {
display: hidden;
position: absolute;
border: solid 2px black;
right: -8px;
top: -8px;
width: 20px;
height: 20px;
border-radius: 50%;
background-color: #000;
color: #fff;
content: "✓";
}```
Even when I check dev tools, 'checkmark' is the className but nothing changes onClick
The function you activate should be onClick rather than onChange.
Usually onChange can be used in <input> and <select>. However, if you are using div, using onChange seems to be a problem.
<div className={`choice_container ${isChoiceClicked ? 'checkmark': 'null'}`} onClick={this.handleChoice}><h5>Yoga</h5><p className="activities">Vinyasa, Ashtanga, Kundalini, Hatha, Restorative, Prenatal</p></div>
Besides, I guess you wanna destructure from this.state. Therefore, you can do the following thing.
const isChoiceClicked = this.state;
const { isChoiceClicked } = this.state;

How can I make responsive images from Ghost (Content API) to Next.js?

I've created a blog website based on this video: https://www.youtube.com/watch?v=1SYU1GorO6Y. Where it has:
Next.js as the frontend,
Ghost CMS as the backend (with Heroku), and
Vercel for deployment.
Also used TypeScript and Sass used for this blog.
I've researched on who to do it but this was the only thing I found: https://forum.ghost.org/t/responsive-images-from-content-api/13481
where it says that they do not currently have it, but this was a last year.
I am not sure if it is a problem on the Ghost CMS or the way I've extracted the information using html <div dangerouslySetInnerHTML={{ __html: post.html }}></div>.
So I would like to know how to make my images responsive or at least center them. I am also open to any suggestions for my first blog website.
[sulg].tsx
const Post: React.FC<{ post: Post }> = (props) => {
console.log(props)
const { post } = props
const [enableLoadComments, setEnableLoadComments] = useState<boolean>(true)
const router = useRouter()
if (router.isFallback) {
return <h1>Loading...</h1>
}
function loadComments() {
setEnableLoadComments(false)
;(window as any).disqus_config = function () {
this.page.url = window.location.href
this.page.identifier = post.slug
}
const script = document.createElement('script')
script.src = 'https://apdv-dev.disqus.com/embed.js'
script.setAttribute('data-timestamp', Date.now().toString())
document.body.appendChild(script)
}
return (
<div className={styles.container}>
<p className={styles.goback}>
<Link href="/blog">
<a>Back</a>
</Link>
</p>
<h1>{post.title}</h1>
<p>{post.reading_time} minute(s) read</p>
<div dangerouslySetInnerHTML={{ __html: post.html }}></div>
{enableLoadComments && (
<p className={styles.goback} onClick={loadComments}>
<a>Load Comments</a>
</p>
)}
<div id="disqus_thread"></div>
</div>
)
}
export default Post
You can grab the class with global jsx :
<style jsx global>{`
.kg-image-card img {
width: auto;
max-width: 100%;
height: auto;
border-radius: 8px;
margin: 1em auto;
box-shadow: 38px 24px 50px -21px #C9D3DF;
}
`}</style>
Rendering the HTML of your rich text is simple, but comes without much customization, so you can put your div inside another div with class and style it.
<div className='post__html'><div dangerouslySetInnerHTML={post.html}/></div>
.post__html img {
width: 300px;
height: 300px;
border-radius: 20px;
}
But all images on the blog post will take the same styles.
If you want more customization, you can fetch the raw version of the blog post, you will have ultimate control over how these nodes are presented to the user, you can read more here
I was able to solve this by looking at the raw output of my dangerously set HTML using the Inspector Tool! From there, I was able to highlight the elements I wanted to edit and see their class or id names for me to target with SASS.
This GitHub was also useful in figuring out the classes Ghost gives to the HTML: https://github.com/TryGhost/Starter/blob/main/assets/css/ghost/content.css

React body scroll lock issue on IOS

I'm literally fighting in finding a clean solution to the scroll issue in the IOS devices. In my App.js i've simply the background body and a modal with some contents. When the modal is shown i'd like to block the scroll in the background (myBodyContent) and still let the scroll in the modal component. I'm quite new to both javascript and React and this not helping me at all.
The cleanest solution (according to me) i was able to find is the body-scroll-lock package but it seems i'm not able to successfully use it. here is my code:
App.js
class App extends Component {
targetRef = React.createRef();
targetElement = null;
constructor(props) {
super(props);
}
componentDidMount() {
this.targetElement = this.targetRef.current;
disableBodyScroll(this.targetElement);
}
render() {
const myModal = (
<Modal ref={this.targetRef}>
// my long content here
</Modal>);
return (
<React.Fragment>
{myModal}
<Layout>
<myBodyContent>
</Layout>
</React.Fragment>
);
}
}
Modal.js
class Modal extends Component {
shouldComponentUpdate(nextProps, nextState){
return (nextProps.show !== this.props.show)
}
render () {
return (
<div>
<Auxi>
<Backdrop
show = {this.props.show}
clicked = {this.props.modalClosed}
/>
<div className={style.Modal}
style={{
transform: this.props.show ? 'translateY(0)' : 'translateY(-100vh)', // vh is special unit for outside screen
opacity: this.props.show ? '1': '0'
}}>
{this.props.children}
</div>
</Auxi>
</div>
);
}
}
Modal css
.Modal {
position: fixed;
z-index: 500;
background-color: white;
width: 80%;
overflow-y: hidden;
overflow: auto;
padding-right: 15px; /* Avoid width reflow */
border: 1px solid #ccc;
box-shadow: 1px 1px 1px black;
padding: 16px;
top: 5%;
left: 5%;
box-sizing: content-box;
transition: all 0.3s ease-out;
}
#media (min-width: 600px) {
.Modal {
width: 80%;
height: 80%;
left: 10%;
top: 10%
}
}
With the above code, simply everything is locked and i cannot scroll neither the modal nor the myBodyContent.
Can you help me understanding what i'm doing wrong? Or suggest me some other ways to achieve the same result?
Thanks in advance for your help.
You don't have targetElement (it's null) inside App componentDidMount because you try to set ref for React component but not HTML element.
To fix this you need to forward ref inside Modal component like that:
const myModal = (
<Modal forwardedRef={this.targetRef}>
// my long content here
</Modal>
);
and then :
class Modal extends Component {
shouldComponentUpdate(nextProps, nextState){
return (nextProps.show !== this.props.show)
}
render () {
return (
<div ref={this.props.forwardedRef}>
<Auxi>
<Backdrop
show = {this.props.show}
clicked = {this.props.modalClosed}
/>
<div className={style.Modal}
style={{
transform: this.props.show ? 'translateY(0)' : 'translateY(-100vh)', // vh is special unit for outside screen
opacity: this.props.show ? '1': '0'
}}>
{this.props.children}
</div>
</Auxi>
</div>
);
}
}
Thanks Max, i've tried but unfortunately the result is the same. I've also tried to enclose the Modal in a div directly in the App.js and apply the ref directly there without passing it as props...but it's the same. No way to scroll anything.

In ReactJs is it possible/feasible to perform rendering during a Drag/Drop operation?

In ReactJs is it possible/feasible to perform rendering during a Drag/Drop operation?
The specific use case I had in mind was trying to build a month view calendar in ReactJS that, during dragging of a multi-day event backwards and forward, all the other day events on the calendar would move backwards forward to show (whist the use is still dragging) what the effect would be on all events before the do actually "drop" it. (i.e. assumes only one event on any given day, so page would aim to move/swap day events around when user is moving one)
Similar to drag dropping a movie clip on a movie timeline, and you see how the clips would swap around during the drag, highlighting what would happen if the user did release the mouse button and do the "drop".
Question: Is is this possible/recommend in ReactJS? If yes, what would be the concept here? i.e. what call would one be making to trigger a "refresh" during the drag event handler? Or if in the drag event handler you just reposition other components/events does React just render on-the-fly during the drag automatically?
Yes - with an example below:
import React, { Component } from 'react';
import 'rc-slider/assets/index.css';
import './GcSlider.css';
export class GcSlider extends Component {
state = {
value: 50,
};
handleChange = (value) => {
this.setState({ value });
};
buttonClick = (e) => {
console.log('Button Clicked');
}
render() {
const { value } = this.state;
let divs = [1,2,3,4,5,6,7,8,9].map(item => <div className="box {item}">Item {item}</div>)
console.log('DIVS = ' + divs)
return (
<div>
<div style={{alignContent:true}}>
<h1>Hello</h1>
</div>
<div className="wrapper">
{ divs }
<div className="box {item}"></div>
<div className="box {item}">Item B</div>
<div className="box {item}">Item C</div>
<div class="overlay" draggable>oevrlay</div>
</div>
</div>
)
}
}
export default GcSlider
and css
.wrapper {
display: grid;
grid-template-columns: 1fr 1fr 1fr;
}
.box {
border-radius: 5px;
border: 1px solid brown;
font-size: 150%;
height: 120px;
}
.overlay {
position: absolute;
top: 0px;
height:80px;
border: 2px solid red;
}

Resources