Asynchronous in data redux components - reactjs

I'm new in reactjs. I'm creating a movie web with redux thunk. At home container, I use axios to call API to get a list of movie data and save it in store.
My home container has a carousel component gets that data on store by useSelector and loop it to render many carousel items. The problem is here. The initial data state in store is null, and while my app call API, carousel component still maps it and get error there:
TypeError: Cannot read property 'map' of null
I have solved this with ? syntax: data?.map()... and don't get that error.
I wonder may we have any solution better than mine? I mean it can waiting until the fetch data success instead of using ?. in any component.
Thank you if anyone help me some solution. You can just give me some key word or library, which is used in real project. I will study to import myselt.
Thank you

use empty array instead of null, as initial state of movie store is empty.

Using ? is the shortest way or you can put an if condition to check the movies array is null or not. something like if(moviesArr !== null) //do the rest...

Related

How to Access Data in Redux Store?

I am building an application and am trying to show article content from mongoDB using axios, node.js, and express on a React frontend. I can pull the data to my redux store but when I try to display it I get a cannot read property 'author' (or whatever property in the state I'm going for) of undefined error.
Here are some screenshots of my react file, as well as the action and reducer. Let me know what other info you might need. Thanks a ton.Here is my React file. Here is the action. here is my reducer.
Because the initial of state is empty object {}. So while fetching API, state.articles is undefined and this issue occur.
You can fix by add condition before using with optional chaining
const articles = useSelector((state => state.articles);
const current = articles?.current ;

How can I iterate over the list of URLs and make a call to the server using useSWR hook

I am working on a ReactJS Web application and got stuck in a problem. Problem is I have an array of URLs of some JSON data and I want to fetch all these JSON data from server using "useSWR" hook (so that the fetched data gets cached as well). Now the problem is as per the rules we cannot use hooks inside any loop or block.
Example -
What I have - ["http://someapi/a.json", "http://someapi/b.json", "http://someapi/c.json"]
What I want to do - iterate over this array and call these urls using useSWR hook, so that I have a list of [ JSON ObjectA, JSON ObjectB, JSON ObjectC ]
Why I am trying to use "useSWR" because I know, this data will not gonna change for 24Hours and I want to cache these values.
Can anyone suggest me how can I iterate over the list of URLs and make a call to the server using useSWR hook? And is there's some other optimized approach to solve this problem? Any help or guidance is highly appreciated.
One of the option i think is to create React FetchComponent with url prop and use the useSWR hook inside.
Render components as number of urls.
Something like this:
["http://someapi/a.json", "http://someapi/b.json", "http://someapi/c.json"].map(url=><FetchComponent url={url}/>)

Issues displaying nested api data in React Application

I am doing a react application and I want to fetch data from an api using the useEffect hook. I am receiving the data, but I am having trouble when trying to display 1 of the items in the received object. I have no problem displaying the other items from the data that I want.
When I look at the returned data in the console I see that the property I am trying to display (and gives me error) is actually object nested inside an array.
The error that I get is "TypeError: Cannot read property '0' of undefined"
I think that the problem is that not all data is loaded in the time when it renders, but not sure how to handle this. The problem is the "coinData.description[0]". Is my approach correct
Here is my component:
Componet First Part
Compoent Second Part
The problem is on row 36 in the second picture
Thanks in advance !
The setCoinData will set the whole answer of your request.
The problem is that property does not exist or that you are trying to render before your fetch was finished.
For the first case you can check the answer with a console.log().
In the second case you can use optional chaining to avoid this error.

what is the issue mobx Error 'Reaction[observerobserved]?

Help me pls with this issue:
I'am using mobx-state-tree + React + mobx + Socket.io ,i'm writing chat for project,and using for connection socket.io
From server i get chats list and then put him to mobx-state-tree store using action,then i want get data from mobx-state-tree store and use map function for render elements
But,i catch two errors
This is my mobx-state-tree model for chat
enter image description here
this is my code where i trying to maping data
enter image description here
this is issue
enter image description here
But error "user" undefined is very stranger,because when i use console.log() for display data,array has this data and displayed in console
Okay,i find problem with Reaction[observerobserved] this happens because component which render chat list was not wrapped into observer function
But i'm still have problem with undefined props of array when i call map method on him
Resolve for |Reaction[observerobserved]"
Need wrapped component into observer() function for subscribing on changes
For second problem, with undefined prop:
first solution wrong on the screen, because you try get undefined index in this case 'item.chat_users[index]", solution is use map for chat_users array to, and then render inner item for this data "item.chat_users.map(....)"

Where should I load data from server in Redux + ReactJS?

For example I have two components - ListOfGroupsPage and GroupPage.
In ListOfGroupsPage I load list of groups from the server and store it to the state.groups
In route I have mapping like ‘group/:id’ for GroupPage
When this address is loaded, the app shows GroupPage, and here I get the data for group from state.groups (try to find group in state via id).
All works fine.
But if I reload page, I'm still on page /group/2, so GroupPage is shown. But state is empty, so the app can't find the group.
What is the proper way to load data in React + Redux? I can see this ways:
1) Load all data in root component. It will be very big overhead from traffic side
2) Don't rely on store, try to load required data on each component. It's more safe way. But I don't think that load the same data for each component - it's cool idea. Then we don't need the state - because each component will fetch the data from server
3) ??? Probably add some kind of checking in each component - first try to find required data in store. If can't - load from the server. But it requires much of logic in each component.
So, is there the best solution to fetch data from server in case of usage Redux + ReactJS?
One approach to this is to use redux-thunk to check if the data exist in the redux store and if not, send a server request to load the missing info.
Your GroupPage component will look something like
class GroupPage extends Component {
componentWillMount() {
const groupId = this.props.params.groupId
this.props.loadGroupPage(groupId);
}
...
}
And in your action...
const loadGroupPage = (groupId) => (dispatch, getState) => {
// check if data is in redux store
// assuming your state.groups is object with ids as property
const {
groups: {
[groupId]: groupPageData = false
}
} = getState();
if (!groupPageData) {
//fetch data from the server
dispatch(...)
}
}
I recommend caching the information on the client using localstorage. Persist your Redux state, or important parts of it, to localstorage on state change, and check for existing records in localstorage on load. Since the data would be on the client, it would be simple and quick to retrieve.
The way I approach this is to fetch from the server straight after the store has been created. I do this by dispatching actions. I also use thunks to set isFetching = true upon a *_REQUEST and set that back to false after a *_SUCCESS or *_FAILURE. This allows me to display the user things like a progress bar or spinner. I think you're probably overestimating the 'traffic' issue because it will be executed asynchronosly as long as you structure your components in a way that won't break if that particular part of the store is empty.
The issue you're seeing of "can't get groups of undefined" (you mentioned in a comment) is probably because you've got an object and are doing .groups on it. That object is most likely empty because it hasn't been populated. There are couple of things to consider here:
Using ternary operators in your components to check that someObject.groups isn't null; or
Detailing in the initialState for someObject.groups to be an empty array. That way if you were to do .map it would not error.
Use selectors to retrieve the list of groups and if someObject.groups is null return an empty array.
You can see an example of how I did this in a small test app. Have a look at specifically:
/src/index.js for the initial dispatch
/src/redux/modules/characters.js for the use of thunks
/src/redux/selectors/characters.js for the population of the comics, series, etc. which are used in the CharacterDetails component

Resources