I am using react and in some pages i am transferring data from url but the problem is when I want that data to persist if url changes until there is any other query or parameter in url.
How can i achieve that?
This is my url snapshot
I want the query data i.e idx=1 to persist if there is any change in url like this
Currently when I link to salesfunnel page I am doing this
`
componentDidMount() {
var url = this.props.location.query;
this.setState({
selid : parseInt(url.idx, 10)
})
}
`
and in that case i lost query.I want that the query should remain somewhere with me if i get it once and the data should only change when there is certain change in query of url for eg: if idx=2 from idx=1.
How can i achieve that in react?
Any help much appreciated!
Thanks :)
Can you not conditionally set the selid e.g.:
componentDidMount() {
var url = this.props.location.query;
if (url.idx) {
// Only update `selid` when `idx` is a query param
this.setState({
selid : parseInt(url.idx, 10)
});
}
}
This way you'll persist the value across page changes until the user lands on a new page that sets a new idx.
Related
I am developing a ecommerce store using NEXT.JS and Redux. So in product listing page, I have sorting select dropdown with Price Low to High, Price High to Low and New Arrivals. Upon selecting this option, I want to change the URL without page refresh and API call should occure. I have tried using below code, but it is not working and page is reloading.
function sortBy(value) {
router.replace({
pathname: '/products/'+slug,
query: { sort: value }
})
dispatch(fetchproducts(slug, sort));
}
The above code just refresh the current page and appending sort param to URL.
So is it possible to do it without page refresh like in Flipkart.
With the help of shallow-routing change of URL without doing a page reload is possible. It can be enabled by passing explicit option object as third argument to Router.push, i.e { shallow: true }
From the docs
Shallow routing allows you to change the URL without running data fetching methods again, that includes getServerSideProps, getStaticProps, and getInitialProps.
You'll receive the updated pathname and the query via the router object (added by useRouter or withRouter), without losing state.
For example, this how you would update the query param sortBy for pathname /products with the help of shallow-routing.
Router.push({
pathname: '/products',
query: { sortBy: 'price' }
},
undefined, { shallow: true }
)
But there are a few caveats It is not possible to do shallow-routing between different pages, it works only for same page URL changes. See the caveat section for more details.
For example, you can update a query param for page /product page, but it won't be possible if you try to do shallow-routing from /product to /product/[slug] because they are two distinct pages.
// page will reload because shallow-routing not possible between the pages
Router.push('/product', '/product/some-product?sortBy=price', { shallow: true })
Example:
you have a folder like: posts/[id].js and your url is like http://something.com/posts/123
You want to add a query param that will not refresh the page and your url will be like: http://something.com/posts/123?param=ok
all you need to do is:
const postId = 123;
const param = 'ok';
router.push(
{
pathname: `/posts/[id]`,
query: {
postId,
param
}
},
`/posts/${postId}?param=${param}`,
{shallow: true}
);
I am trying to get better in react and I would like to do it everything correctly which is why I am asking for your opinions and help.
I am building a project in NextJS and I have a layout component which contains components which are rendered multiple times such as header, footer etc.
I this header, I have a "Sign in" and "Sign out" button. I'd like it to only show one of them accordingly to your session status.
I use a sessionid which contains some more info in the database and this sessionid is stored in a httponly cookie.
It is stored in the database with data:
id
sessionid
userid
expires
Would you add or remove anything to this?
So my question is:
How would you check for a session and then render x accordingly? Would you just send an api call each request that checks the session or? Should I maybe use useContext and create a provider which can then send the session with the provider?
I'm quite lost on how to do it the best way so the flow is smooth as f*ck.
It depends how strict you want to be with it.
One option would be to simply check the existence of the cookie and adjust according to that. You can use js-cookie for that.
The better option, in my opinion, is to verify the cookie with your backend. You should set up an endpoint that simply verifies / parses the cookie and returns something like the user_id, or ismply a boolean indicating whether the user is logged in.
Given that you are using Next, you can add this call to your App's getInitialProps() like this:
App.getInitialProps = async () => {
let loggedIn;
try {
({ data: {loggedIn} } = await axios.get('/api/v1/auth/checkCookie'));
} catch (err) {
console.log('Error checkingCookie', err.message );
}
return {
loggedIn,
}
}
Your loggedIn variable will then be available in the props of your App, like:
function App({currentUser}) {
if (currentUser) {
return <div>Logged In</div>
} else {
return <div>Logged Out</div>
}
}
I am currently working with react and react-router and I'm building a page that shows details of a certain item that gets its data from an API when the page mounts. The fetch method requires the item's id so I'm using match.params.id to get the value for the fetch method. I also am using the slug package in the backend to show the title for that item in URL format alongside the id. I want users to be able to type in the URL with the slug title and not have to worry about typing the id in order to be directed to the page with the correct data.
For example, clicking on the item on the UI will make the URL look like this: localhost:3000/the-title-slug/123456.
You have to actually click on the item on the UI to get the URL to have the id but I want to make things simpler for the user and make it so that if they only type the slug title: localhost:3000/the-slug-title, it will redirect to the correct URL with that slug and id.
Any ideas on how this could be done? Kind of like if you type googel.com it corrects the typo and directs you to google.com. Any help figuring this out would be very appreciated, thank you.
Your backend must to have the API method to get correct item by misspelled slug.
like:
requestData: the-slug-title
responseData: the-title-slug, 123456
and then your component have to handle wrong url
componentDidMount() {
const { params } = this.props.match;
const respose = await fetch({ ... })
this.setState({ id: response.id, slug: response.slug });
}
render() {
const { params } = this.props.match;
return this.state.id && this.state.slug && (this.state.id !== params.id || this.state.slug !== params.slug) && <Redirect to={`/${this.state.slug}/${this.state.id}`} />
}
I have an app that takes a search string and returns results in one route : hosts.abc.com:3000. The url doesn't change.
I want the search to be reflected in the url so I can share the link and users don't have to make all selection in the form fields.
eg: hosts.abc.com:3000/?type=all&query=coins
Is it possible to do this using react-router ?
To construct such query you could use native browser URLSearchParams:
const searchParams = new URLSearchParams();
searchParams.append("type", "all");
searchParams.append("query", "coins");
searchParams.toString(); // "type=all&query=coins"
// update browser url
this.props.history.push('/current/route/?' + searchParams.toString());
// or
this.props.history.push({
pathname: '/current/route/',
search: searchParams.toString()
})
But if you want better support query-string is a similar option.
I couldn't think of a reasonable title for this post.
The problem I'm having is that I have an SQL database attached to my MVC website. Within the website I have a news/blog system that I have worked on which stores the data in the database and pulls the information on request.
The problem is the routing. I currently have it set up to pull the information about the routing of each individual page as this:
var newsr = new NewsResources();
foreach (var item in newsr.GetAllNewsItems())
{
item.Title = item.Title.Replace(' ', '-').ToLower();
routes.MapRoute(item.Title, "News/" + item.Title,
new {controller = "News", action = "Post", id = item.ID});}
When I add a new news item however, this doesn't go into the routing system which is proving to be a right pain. I've had a google search for dynamically adding url routing but I can't seem to find a solution.
What I want to know is, is it possible to add a page to the routing system via the page controller once I have saved the post into the database?
I do not think you need to Do a For Each loop across all your POst item and add routes for that. You may do it like this
public static void RegisterRoutes(RouteCollection routes)
{
routes.MapRoute("SingleItem", "News/{title}",
new { controller = "Items", action = "PostFromTitle" });
// and the generic route
routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Home", action = "Index",
id = UrlParameter.Optional }
);
}
This will route ../News/SomeTitle request to your PostFromTitle action method of NewsController. Read the title there and get the post from there.
public ActionResult PostFromTitle(string title)
{
var post=repo.GetPostFromTitle(title);
return View("~/Views/News/Post.cshtml",post);
}
It may be better to an action that takes a title as a parameter.
routes.MapRoute("NewsItem", "News/{title}",
new { controller = "News", action = "ShowNews" }