i am trying to code a simple dashboard with React, node and mongo.
Register and Login works well:)
So now i want to display the User Name on the Topbar with his Picture. I load the data (name and picture url) in the Topbar component via Ajax from the Server. So right, soo good.
Soo, but i need User Data for a lot of other components. (Friends, Notifications and soo soon) i can't in every componente an ajax call to my server make or? But i don't understand how to do this.
I need Data from the same Model in many different components.
You can use the context api or redux to create a 'global' store and access any data in it from anywhere down or up the component hierarchy without having to pass props down each level. In redux you can access any piece of this global state with the connect hoc.
More on redux
More on context api
Comparison of the two
Related
I have been using react and redux and everytime ,I make a call to some rest api in ComponentDidMount ,I can set a state with it and pass that state onto my child or change that state and play with it .
I can keep that data in my redux too and do all what i want .
I recently started using graphql and I see that as one fetches data inside render using a query , we render the data that we want to and so on .
But I am concerned as how instead of rendering it ,I can store it in some state ,play with it and then pass it down to the child .
I came acroos this link state in apollo but couldn't have a clear understanding of it as what it basically does ?
How to solve this issue of state management and playing with that state which is set by the data coming from the apollo .
I am really missing out this feature of
this.setState({
data:(some api data )
)}
Suppose I made a query and I want three of my Child Components to share the same data .How will you achieve this with graphql ?
1st method
Data read from api is accessible via the cache - default policy is cache first. Each of children can access data from cache using graphql (HOCs or components). Each of them can use a different query to get data the component really needs. If all of queries fields are subset of parent query - you can use cache-only policy.
2nd method
You can manipulate api data using getDerivedStateFromProps(). You can pass these values directly as props to the childs (w/o using graphql cache access).
3rd method
React classic (pass props down the tree): simply pass data prop (unmodified) to child rendering <Child data={this.props.data} /> (parent inside HOC) or <Child data={data} /> (render prop within <Query/> component)
So imagine I have these 2 URLs:
example.com/Profile
example.com/Profile/City
When example.com/Profile is visited, I present component Profile and when example.com/Profile/City is visited, I present component City.
I need to make a GET request that returns information used in both components. Currently, I make that GET request in the mounted() lifecycle hook of both components but I have been wondering if I can do it once only in the parent Profile component and then just props it down to City so that I could get rid of 1 GET request.
However, I am not sure what would happen if a user straight up types example.com/Profile/City? Considering the GET request is executed on mounted() of the Profile component and we haven't mounted Profile since the user straight up typed the URL that leads to City component , will I have the response in the child component?
Considering the GET request is executed on mounted() of the Profile component and we haven't mounted Profile since the user straight up typed the URL that leads to City component , will I have the response in the child component?
No, you won't. You will end up with no data.
I have been wondering if I can do it once only in the parent Profile component and then just props it down to City so that I could get rid of 1 GET request.
Not really. However if you used a global state management solution like vuex, you could move the request and the data into this global state and trigger the vuex action for the request from both component's mounted.
Then you could implement logic in your vuex action that would skip the request if the data is already present (i.e. from having previously visited /profile). But in that case you should make sure to save some timestamp so you don't cache the data indefinitely.
If you expect the data to change frequently, I wouldn't cache it like that at all and rather do a duplicate request everytime to ensure the data is a fresh as possible.
I have an isomorphic react application using redux,react-router, react-router-redux, I want to bind my components with url query params and when the query params changed, send request to an API and update my state and finally fetch data.
I know with react-router-redux it automatically update my state.
Also I want to show a pre-loader (spinner) to user when data is fetching.
what is the best way to write an action creator for this issue ? thanks
I want to show a pre-loader (spinner) to user when data is fetching
Pass a data prop to your component. When it's undefined, show a spinner.
const MyComponent = (props) => {
if (!props.data) return <Spinner />
...
}
When the query params changed, send request to an API and update my state and finally fetch data
The most simple solution (this can get quite complex depending on your needs) is to fire this logic on the Component's lifecycle hooks.
When the route changes react-router, with a typical configuration, will cause the component to render if you were previously on a different route, and update if you were previously on the same route (i.e. the same path, but with different query params).
So for the first case, use componentDidMount, for the second case, use comonentDidUpdate(prevProps, prevState) lifecycle hook.
To map the asynchronous API call to redux action(s), use a library like redux-thunk or probably more tailored to this use case, redux-promise-middleware. How to use those is a bit deep in scope for me to go into here, but they both have excellent documentation.
In the end, you'll want to map those actions in a reducer put the response data somewhere in your state tree, then using react-redux bind that location in the state tree to the data prop on your Component, as I mentioned before.
Im new in React and single apps and I have a question in this approach.
Im using React-router 4. When routing lets say I have a ToDos component (myapp.com/todos) that when visiting I fetch the ToDos data to something like "myapp.com/api/todos.json" and get the ToDos list and then render every ToDo, and if I want to go to something like ToDo component where you show the ToDo details would be a route like "todos/:todoid" then I use a and go to the ToDo detail and that works fine, but what happen when a user visit directly the "todos/1"?. Should I fetch the data from the server corresponding to that particular todo? something like "myapp.com/api/todos/1.json" ? or should I load the ToDo component and get all the todos ?
Is important because then I have to server rendering the routes and pass some props to the route like the open graph tags.
Any advice or tutorial or course would be appreciate. thanks in advance!
You don't need server side rendering, when the user opens 'todos/1' directly, then render ToDo-detail component and use onComponentDidMount to fetch('api/todos/1').
My app uses react-router, redux, react-redux. Lets say I'm currently looking at /about route which renders the AboutPage component. Now I want to navigate to /news. Right now, when the route change happens the new component mounts, which fires off async actions to fetch the data. While that data is being fetched I am looking at the NewsPage component but with loading spinners.
What I'm trying to do is stay on the AboutPage component while all that data fetching is happening. I have successfully implemented the data fetching during react-router's onEnter hook. The problem is that, if AboutPage happens to use any of the same redux state as NewsPage, you'll see rendering changes while the data is being fetched and updated.
What I'd like is to somehow 'freeze' the current route while actions/state-changes are happening behind the scenes, and then render the new route component when thats ready (in the meantime users will see loading feedback via https://github.com/rstacruz/nprogress).
So either I need to completely unsubscribe the current route component from state changes or otherwise lock stuff in. Not sure if redux even exposes what I need but curious if others have solved this.