React ancor doesen't scroll down on reload - reactjs

Im using React v6 and trying to implement ancors. I want that i can get the link of a subtitle so that when i send it to a friend the page is opend and scrolled down to the subtitle. I found out that Ancors are used for that but couldnt find a solution that works. When I navigate on the page via the link it works and it scrolls to the subtitle but if i close the tab and open it again this time with the link and the ancor it doesent scroll down.
does someone know an easy solution for this problem?

Please use
import { useEffect } from 'react';
function ContentContainer({ header, content, descriptionExample, additiv, linkToSite, linkText }) {
useEffect(() => {
if (typeof window !== 'undefined') {
// Check if the current URL has a hash
if (window.location.hash) {
// Get the element with the corresponding id
const element = document.getElementById(window.location.hash.substring(1));
if (element) {
// Scroll to the element
element.scrollIntoView({ behavior: 'smooth' });
}
}
}
}, []);
return (
<div id={header} className={style['content-container']}>
<div onClick={() => iconClicked(header)} className={style['content-container-header']}>
<Link smooth to={header}>{header}</Link>
<div className={style['header-anker-icon']}>
<InsertLinkOutlinedIcon className={style['link-icon']} />
</div>
</div>
<div className={style['content-container-content']}>{content}</div>
<img className={style['content-container-img-example']} src={example} />
<div className={style['content-container-description']}>{descriptionExample}</div>
<div className={style['content-container-additiv']}>{additiv}</div>
<a className={style['content-container-link']} href={linkToSite}>
{linkText}
<InsertLinkOutlinedIcon className={style['link-icon']} />
</a>
</div>
);
}
export default ContentContainer;

Related

React - Replacing a component with another on button click

I've two React components, I want a button click in one to replace it entirely with the second.
This is my App Component:
const App = () =>{
const[showMarketing, setShowMarketing] = useState(false);
const[showLanding, setShowLanding] = useState(true)
const toggleViews = () =>{
setShowMarketing(!showMarketing);
setShowLanding(!showLanding);
}
return (
<div>
{showMarketing && <Marketing/>} {showLanding && <Landing toggleViewFn={toggleViews}/> }
</div>
);
}
export default App;
This is the Component that is rendered by default:
const Landing = ({toggleViewFn}) =>(
<div className="shrink-wrapper">
<header className="small-vertical">
<figure className="logo">
<a href="">
<img src={logo} onClick={() => toggleViewFn()}/>
</a>
</figure>
<nav>
</nav>
</header>
</div>
);
This is the component that I want to render on the img click:
const Marketing = () => (
<div>
......Something here
</div>
);
In the current code, the switch happens for a second and the the UI is back to the Landing component. I can't seem to understand why?
I'm new to React, any help appreciated.
The problem is that your <img/> with the onClick is wrapped with an anchor-- when you click the <img/>, the click handler is fired but the anchor click is also registered and the browser navigates. I suspect if you remove the wrapping <a> this will work as expected.
Ultimately, if you are trying to use this for routing, you'd be better off leveraging a library like React Router; while you could try to manage your own routing on your own, it can be complex and is rife with accessibility pitfalls (for instance, using anchors with empty hrefs to wrap items with onClick handlers is not particularly accessible). Hope this helps.

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.

react-scroll Link renders as text and is not clickable - smooth scroll does not work

I am following tutorials online for how to use react-scroll but I cant seem to get it working for me
I am using the Link tag from react-scroll and setting the 'to' attribute to the id of the div I want to scroll to. But when I view the live code the Link I have renders as text and appears to be unclickable.
import { Link } from "react-scroll";
const OpenBlurb = () => {
return (
<div className="blurb-container">
<h1>Welcome</h1>
<Link to="projects" smooth={true} duration={500} offset={50}> My Projects </Link>
</div>
);
};
export default OpenBlurb;
I want the 'My Projects' link to smooth scroll down the page to another component with the id 'projects'
const SecondSection = () => {
return (
<div className="second-container" id="projects" >
<h2>My Projects</h2>
</div>
);
};
export default SecondSection;
Can anyone see what I am doing wrong?
I am guessing "projects" are not identified as an ID.
Have you tried using to="#projects"?
Take a look at these, they might help:
How to scroll to an element?
react-scroll | How to scroll to a specific targeted component when clicking on Navbar Link

The Use of "Navigate(-1)" Fails to Return to Previous Location in Gatsby

I am trying to create a simple "Back" button in Gatsby that returns the the previous page and retains the scroll position. This already happens when using the browser back button, but I'm struggling to produce a custom one. I've read in the Reach Router docs that you can add -1 as an argument to the navigate function to return to previous locations, but It instead throws the number value into the url and gives me a 404. Can someone give me an idea of what I've done wrong? Or if anyone else has managed to make a functional back button for Gatsby projects?
Here is my code-
import React from 'react';
import { graphql, navigate } from 'gatsby'
import Img from "gatsby-image"
import "./design.scss"
const designTemplate = (props) => {
return (
<section className="design">
<div className="design__container">
<h2 className="design__title">
{props.data.design.title}
</h2>
<Img className="design__image" fluid={props.data.design.localImage.childImageSharp.fluid} />
<p className="design__summary">
{props.data.design.summary}
</p>
</div>
<button onClick={navigate(-1)}>Go Back</button>
</section>
);
}
The issue you're having here is just that you didn't define a callback function for your onClick handler.
Instead of this:
<button onClick={navigate(-1)}>Go Back</button>
…you want to do this:
<button onClick={() => { navigate(-1) }}>Go Back</button>
Your onClick must have a callback(arrow function) like this
onClick={()=>{navigate(-1)}}
not
navigate(-1)

Ckeditor disable auto inline won't disable inline from being selected on page load

I'm trying to develop a simple CMS for my page. I want it to where I can edit and delete a users reply on click of a button. I got the delete functionality done so I figured for the reply functionality I would use CKeditor. What I'm struggling with is not being able to disable the autoinline feature. I can still select my div on load of the page rather than clicking a button to enable the inline feature but I don't know what I am doing wrong?
I have tried setting the feature directly in my index.html file, a custom js script file and the config.js ckeditor file but none worked. I am using Ckeditor 4.
this is the snippit of code I'm trying to use to disable inline on my div element but it's not working and I don't know why, i currently have it placed in a custom.js script file and I'm calling it from my index.html file
CKEDITOR.disableAutoInline = true;
Here is my code for my replies page:
import React from 'react';
import CKEditor from 'react-ckeditor-component';
import ForumpageService from '../../services/forumService';
import appController from '../../controllers/appController';
class Forumreplies extends React.Component {
constructor(props){
super(props);
this.elementName = "editor_" + this.props.id;
this.editReply = this.editReply.bind(this);
this.state = {
reply: '',
errorMsg: '',
isLoggedin: false,
// Ck Editor State
reply: '',
}
}
async componentDidMount(){
const topicId = this.props.match.params.topicid
const postDetails = await ForumpageService.replyDetails({topicId: topicId})
this.setState({
postDetails: postDetails[0],
topicId: topicId
})
await this.postReplies();
}
// Edit the reply
async editReply(id, e){
//CKEDITOR.inline(this.elementName);
}
async postReplies(){
const repliesData = await ForumpageService.postreplyDetails({topicId: this.state.topicId})
await this.setState({repliesData});
}
render(){
const repliesData = currentReply.map((row, index) => {
return (
<div className="row" id="reply-messages" key={index}>
<div className="col-md-8" suppressContentEditableWarning contentEditable="true" id={this.elementName}>
<p dangerouslySetInnerHTML={{__html: row.reply_message }} />
</div>
<div className="col-md-2">
{this.state.isloggedinuserId == row.reply_user_id && this.state.isLoggedin == true ? <i className="far fa-edit" onClick={this.editReply.bind(this, row.reply_id)} title="Edit this reply?"></i> : null }
</div>
</div>
})
return (
<div className="container" id="forum-replies">
<div className="row">
{repliesData}
</div>
</div>
)
}
}
export default Forumreplies;
Instead of creating a div and calling CKEDITOR.inline, you should try to use the react-ckeditor-component as its own way (not as an inline editor).
You could do something like: if the button wasn't pressed, render a div with the text content, but after the button was pressed, render a <CKEditor /> component as in the documentation
There is no documented way to set the editor as inline in this package that you are using.
EDIT:
I can see you are not using the react-ckeditor-component features, but following what you've done so far, you could set the contentEditable="true" property of the div only when the button is pressed:
<div className="col-md-8" suppressContentEditableWarning contentEditable={this.state.isEditing} id={this.elementName}>
<p dangerouslySetInnerHTML={{__html: row.reply_message }} />
</div>
And then set the isEditing to true on the onClick handler. Your component will update and then re-render with the contentEditable property set to true

Resources