I know how this.$forceUpdate() work and not trying to just re-render the component.
In Nuxt apps, page components have asyncData() as their lifecycle methods, executed before created(). I'm using it to fetch some initial data and SSR them.
The reason I want to reload the component is to fetch the data again after modifying the corresponding data inside the component, using AJAX. I've tried this.$forceUpdate() just in case but didn't work. this.$router.replace(this.$route.path) also didn't work. I'm trying to not use location.reload() since I have a toast message should be shown after the modification.
Is there any way to do this? Or should I move my fetching part to fetch() and call this.$fetch()?
this.$nuxt.reload() was the thing. Not sure if it exists in Vue itself.
Related
I have a React app(Gatsby) and using #reach/router.
There are multiple pages like user page, follower page...etc.
Fetching data in useEffect hook and here is the problem.
When I navigate to another page from the current page, I'm passing a param, sending it to the next component, for example to a user page, then calling API in useEffect hook in the component with the param. Then you can go to another component like follower page with a param, calling api in useEffect again.
When I try to go back with browser back, the previous data updates again. Ideally I don't want it to get updated every time when I go back to the previous page.
I understand that this happens because I'm calling it in the useEffect hook. Thought about passing data as props with navigate (ex. navigate("/follower", state: { data })), but I think navigate to the page first and fetching data is the best solution for users because when fetching data is taking some time, I want to show skeleton or a loading indicator in the next page. The ideal experience is something like twitter.
Not sure this isn't working because I'm using #reach/router instead of react-router-dom
Any advise is appreciated.
EDIT:
Apologise for my poor explanation.
My problem here is when I keep going back to previous pages like this user page → follower → (another)user → follower ... , browser doesn't remember what were there and useEffect fires everytime. It wasn't happening with react-router before?
My guess is that since I'm using GatsbyJS(SSR) and client-side routing, somehow it generates pages every time even the browser back triggered instead painting it again? I'm not familiar with SSR w/ cliet-routing, hoping to get some info somewhere..
The only way it comes to my mind is using local storage or cookies, within a useEffect with deps ([]), otherwise, each rendering of the page (moving back and forward for example) will trigger again all side-effects available.
Alternatively, you can use useEffect's deps, to only fire the useEffect if the needed dependency has changed.
const SomePage=(props)=>{
const isLoggedIn=props.isLoggedIn || localStorage.getItem('logIn')
useEffect(()=>{
// this will only be fired when yourDeps changes
}, [yourDeps])
return {isLoggedIn ? <div>Hello ${user}</div> : <Link to="/log-in">Log in</Link>
}
You deps (yourDeps) can also check values that you are sending through the location state or from local storate/cookies.
You can also use useRef hook to store "old" values from references but given your generic explanation, I'm not sure which case fits you better.
I was curious to know if making an API request outside of the lifecycle/useEffect is a valid way to make the call?
https://stackblitz.com/edit/react-useeffect-button has two functional components, the parent component makes an API call and passes the data to the child component, initially specified the limit of data to be fetched from the endpoint as 2 and the parent component has a LoadMore function that is passed as a prop along with the data to the child component.
Using the react-slick slider to display the images in the child component and the Load button onClick will call the function LoadMore inside the parent component and then it makes an API call and appends the new data from API to the old Data. The load button will append one Image to the existing images.
is this a good way to make API requests or should it be done only in the lifecycle methods?
is this a good way to make API requests outside useEffect/lifecycle.?
It depends on your requirements.
should it be done only in the lifecycle methods?
It depends on your requirements.
There's nothing wrong making API request outside useEffect. But it should be done in some other function or it will cause the request to go on every re-render.
And if the response if being saved in a state variable.
Then it will go into the infinite loop.
When do we make the request in useEffect and when by some other function?
Requests that fetch data or send some info at the time of initialization of the component is supposed to be made in componentDidMount/useEffect
And requests that are supposed to be sent on some action (like in your case, onClick) so they are hit according to that event.
There's neither good or bad, it's all about your requirements.
If you are making an API call to get data from initial render then using a lifecycle hook is a good approach. In your scenario, you want to make an API request when hitting a button. In that case it can be a simple function without any lifecycle hook method.
The only key part here is that you are maintaining the state and rendering the view from the state.
This depends on your needs.
if you think whenever your params change,API call will be triggered.
in this case, you should set the API call inside the useEffect.
If you want your API call triggered on page load(ComponentDidMount). In this case, you should set API call inside the useEffect
Otherwise no need to set api call inside useEffect.
In your case no need to set API call inside useEffect. because you hit the API call when the user clicks the button. So no need to use useEffect.
suppose I want to have a data provider element for my user, like
<user-data-provider user-data="{{data}}"></user-data-provider>
which sends an ajax request and gets the logged in user.
Suppose I want to access my user data in different pages, and I add this tag to wherever I need, but the problem is, every time the browser sees this tag, makes an ajax again and I have to wait until data is fetched!
I know I can make a variable in my main page and pass it along child pages, but that seems like overkill to me !
how can I persist user data across different pages and part of my app?
thank you in advance
There are different ways to do this.
You can use use a monostate pattern
You can have one instance of your user-data-provider element in your root element or index.html and use iron-signals to transmit the data to all other elements that want to consume it
You can use iron-meta to have global state
Use an external state management framework (i.e. redux). There is a polymer wrapper for it: polymer-redux
I would recommend using an external state mangement framework such as redux.
Some of the solutions are shown here:
Polymer 1.0 Global Variables
I used pouchdb for my data store, and used polymer's predefined elements to work with it
now every time that I need data, I just use that component
We are building our website with react/react-router/redux
We want to server side render our pages that should be filled by the data from our data sources. This transaction has to be asynchronous and unfortunately since we want to server side render, we can not use "componentDidMount" function.
In the redux tutorial page at server side rendering section here, it has been advised to :
If you use something like React Router, you might also want to express
your data fetching dependencies as static fetchData() methods on your
route handler components. They may return async actions, so that your
handleRender function can match the route to the route handler
component classes, dispatch fetchData() result for each of them, and
render only after the Promises have resolved. This way the specific
API calls required for different routes are colocated with the route
handler component definitions. You can also use the same technique on
the client side to prevent the router from switching the page until
its data has been loaded.
This is currently how we handle our data fetch. I personally did not like this approach it looks quite clumsy and it is too coupled to the routing library. Are there any better ways to do it - hopefully with standard react/router/redux components ?
Something like a static fetchData() method is the correct way to handle data fetching with React Router in the general case, though it can reach down into child components as needed (which is e.g. how Relay works).
The reason you want to do it this way is that React Router resolves all the matched routes all at once. Given that, you can then run data fetching for all of your route handlers simultaneously.
If instead you tied data fetching to instance-level handlers on components, you'd always end up with fetch waterfalls, where a component could not fetch its required data until all of its parents receive their required data, and so forth. While that may not be a big problem on the server, it's hugely suboptimal on the client.
If you really want to colocate data dependencies to components, you can consider using something like React Resolver, but this can easily lead to a suboptimal experience for your users.
I have a react contain that makes an ajax request via #asynConnect. Once that data comes back from the server, this component's render method will conditionally render several components. Some of these components have their own data that is required to render their content. What is the best way to fetch the data for each child component? Do I use componentWillMount? Should my parent container dispatch another action that when received will make the subsequent ajax calls? Should I use some type of middleware (redux-thunk)? I've read multiple posts and comments on this topic and still not sure if I've come across a "best practice". FWIW I'm using this project: https://github.com/erikras/react-redux-universal-hot-example