Changing the route when opening a modal but not navigating to it - reactjs

Instagram example
As in the image above, in the user profile page with a url(profile/:username), the user is able to click on one of his posts which opens a modal containing that specific post, the url thereafter changes to p/:postId but doesn't navigate to another page, it instead displays above the profile page without navigating to p/:postId
I'm trying to do the same in my app and I have tried doing stuff like history.push but it's not working and I assume this is happening cause of react-router.

To achieve the behavior you described, you can use React Router to manage the URL change and display the modal with the post content.
Define a route in your React Router configuration that corresponds to the modal content you want to display. For example
<Route path="/posts/:postId" component={PostModal} />
In your component, include a link to the new route with the post ID as a parameter.
<Link to={`/posts/${postId}`}>View Post</Link>
In your PostModal component, use the useParams hook to access the post ID parameter from the URL. Then, fetch the post data from your API or store, and display it.
import { useParams } from 'react-router-dom';
function PostModal() {
const { postId } = useParams();
// Fetch post data and display it in modal
}
After that, Use CSS to display the modal as an overlay on top of your existing content, and use JavaScript to show and hide the modal as appropriate.

Related

How to Reload in ReactJS without refreshing the page?

I want to reload my ReactJS Page without refreshing it! There will be 'reload icon' in the page if some person click it then it should not Reload the page it should be single Page only!
Don't tell window.location.reload();
consider conditionally early returning the Redirect component : https://reactrouter.com/web/api/Redirect
so on your button click; setReload(true);
in your page component:
// before your regular return
if(reload) return <Redirect to={window.location.pathname} />;
If your component is a class component you can use this code below in the click function. this.forceUpdate().
if your component is a functional one you can follow this answer

Dynamic form only shown on refresh

I've been having an issue where the client has provided me a third party Marketo form to include on one of the pages I'm building out which works on a "normal" html page when testing locally, however on Gatsby, it's not working. The script that was provided is as follows:
<script src="//app-xxxx.marketo.com/js/forms2/js/forms2.min.js"></script>
<form id="mktoForm_xxxx"></form>
<script>MktoForms2.loadForm("//app-xxxx.marketo.com", "xxx-xxx-xxx", xxxx);</script>
I've added the top script tag into gatsby-ssr.js like so:
import React from 'react'
export const onRenderBody = ({ setPostBodyComponents }) => {
setPostBodyComponents([
<script
key="mktoForm_test"
src="//app-sjst.marketo.com/js/forms2/js/forms2.js"
/>,
<script
key="/js/site.js"
src="/js/site.js"
/>
])
I've added the following to /static/js/site.js to initialize the form:
MktoForms2.loadForm("//app-xxx.marketo.com", "xxx-xxx-xxx", xxxx);
Then, on the page where I want the form, I've added this:
<form id="mktoForm_xxxx"></form>
The form only displays when I'm on the page and manually refresh the browser. Clicking into the page from any other page does not render the form at all. I'm guess it's how Gatsby/React routes to the page with the form.
Can someone please help??
You probably need to call that .loadForm function when the component that has that form mounts.
React.useEffect(() => {
// load form here...
}, []
If it's just being called in site.js, it's probably being called before the form element is present in the DOM so it has nothing to attach to.
I created this example a while ago, leaving it here in case it's extra help: https://github.com/CharlieDieter/react-marketo-hook

React router - history.push to a specific section of page

In React router, can I use history.push to change the page, and also go to a specific section/anchor on the new page? For example:
history.push('/home#section1');
In my home page I have this:
<div class='back backCard backCardFour ' id='section1'>
<div>
Then please don't hesitate to contact us, you can
use "Send us your thoughts that it's located on the
top of the page and ask us everything or give some
suggestions to improve our work
</div>
</div>
React Router itself doesn't support anchors.
You can use something like React Router Hash Link for that.
You can redirect with props, eg.:
history.push('/home', 'section1');
And then inside your '/home' component check for these 'redirect' props. If there is one, call a scrollIntoView function:
componentDidMount() {
const view = this.props.location.state;
const section1 = document.getElementById('section1');
if (view) {
section1.scrollIntoView();
}
}

How to prevent user from going back in react-router-dom?

I'm using react-router-dom for routing in my reactjs app. And i want to prevent user from going back after login i.e i don't want to user go back again on login screen when he hit back button on browser after login.
Using componentDidUpdate method of React page lifecycle, you can handled or disabled go back functionality in browser. basically componentDidUpdate method will call automatocally when component got updated. so once your component is updated you can prevent to go back as below.
componentDidUpdate() {
window.history.pushState(null, document.title, window.location.href);
window.addEventListener('popstate', function(event) {
window.history.pushState(null, document.title, window.location.href);
});
}
This will prevent to user go back and uses the current page as a refernce for history object . so incase of user even click on back button of browser, they can not go backword in the last page.
You can checkout this codesandbox example may be that will help you or someone who is looking for the same.In this we can prevent the user to go back to previous page,For more detail checkout this medium article. here is small part of the code
componentDidMount() {
const { history } = this.props;
window.addEventListener("popstate", () => {
history.go(1);
});
}
for full working example click on this link.
Are you using redux? other wise you can add something on your render that checks if the user is already logged in it redirects him back to the page he was like:
import { Redirect } from 'react-router'
render(){
//I store my user JWT on this.props.currentUser redux state
this.props.currentUser && <Redirect to={'whatever page you want'} />
//OR you can also, if you have history, history.goBack()
So instead of forbidding going back, you forbid the user to ever going to the login page while logged in, it redirects him somewhere or back to where he was
window.addEventListener('popstate', function(event) {
});
use this function this will read your browser back button click event and after that whatever condition you want you can apply

react router multiple goBack

I have a react app with react-router. I have multiple routes, and some of them are shown in a modal window. If I close the modal, I want to send back the user to the previous page, where modal was not active yet.
To know, if I have modal open, I use the state modal:true on the location. I know I could use simply history.goBack(), but I have the scenario when I'm on /login and the user goes from there to /register, but both routes show a modal. In this case, if the user clicks the close button on the modal, they will go back first to /login.
I tried to do something like this, but the history object is not updated with the new state.
goBack = () => {
while(true) {
history.goBack();
if (!history.location.state || !history.location.state.modal) {
break;
}
}
}

Resources