what's the difference between these two callback in react-redux? - reactjs

I am learning react-redux with the Udemy course. Meet this code,
export function createPost(value, callback){
const request = axios.post(url, value).then(() => callback());
}
why not just put the callback like this
const request = axios.post(url, value).then(callback);
EDIT
in the video they call this function like this
this.props.createPost(value, () => this.props.history.push('/'));
2.
Since they called by this.props.createPost(value, () => this.props.history.push('/'));
I thought the callback is already a function () => this.props.history.push('/') ;
so why they wraped the callback again in the definition createPost by Promise.then(() => callback())
In my opinion just put the callback like Promise.then(callback) is ok.
Am I wrong?

if you take a closer look your function call takes one param, which means if you append parenthesis at the end it will be IMMEDIATELY called:
this.props.history.push('/')
if you try to do:
this.props.createPost(value, this.props.history.push('/')); // without the () =>
the function history.push will be called immediately, what you are doing is context binding, by creating a lambda function you are delaying the execution and also adding a constant param '/'.
Another way to achieve this:
this.props.createPost(value, this.props.history.push.bind(null, '/')
Read Bind
If your function did not take any params then you could do as you wish (without the parenthesis ofc)
this.props.createPost(value, this.props.anotherFunction) // anotherFunction does not take any params, and does can be passed as is

Related

Call multiple async functions using useEffect

I have the following function that makes a call to the api
useEffect(() => {
loadMarkets();
}, []);
async function loadMarkets() {
const marketInformation = await frService.getMarketInfo();
addMarketInfo(marketInformation.response.data);
}
I want to make a similar call to loadBooks(). If I don't mind which method comes first, would I be able to just call it like below or should I be wrapping this in 1 async function/wrap it in a Promise?
useEffect(() => {
loadMarkets();
loadBooks();
}, []);
async function loadMarkets() {
const marketInformation = await frService.getMarketInfo();
addMarketInfo(marketInformation.response.data);
}
async function loadBooks() {
....
loadMarkets();
loadBooks();
because these function are prefixed with the async keyword, these are promise. loadBooks will be fired before loadMarkets finishes.
simple answer, yes you can do as you wrote, however I would try to catch the errors with something like
loadMarkets().catch(doSomethingIfThereIsAnError)
where doSomethingIfThereIsAnError would be a function that does som...
It doesn't really matter which comes first since both of them are async. During the initial rendering of your component, useEffect will invoke both async functions. If you need to check which api endpoint gets called first and how much time it takes for the execution, you can open browser dev tools and check the network tab.

React Native Async Call in Render Function

This question is similar to some that have already been asked, such as (Can you make render() method in React Native async?), however none of these solutions I have found so far work for me. I am attempting to display a value from storage, however it needs to be obtained asynchronously, so when I am trying to render it returns an unresolved promise.
These functions store and get the data asynchronously:
const storeData = async () => {
try {
const value= "hello"
await AsyncStorage.setItem('#storage_Key', value)
} catch (e) {
}
}
const getData = async (key:string) => {
return (<Text>{await AsyncStorage.getItem('#storage_Key')}</Text>)
}
...and then in my return I am trying to do this:
<Button
onPress={() => storeData()}
title="Store"
color="#841584"/>
{getData()}
Which I want to display a button that saves data (working I think), and then display that data in a text field. However I keep receiving unresolved promise errors. How can I render something alternate until the value is loaded, and display the data without an unresolved promise?
You must use promise instead async/await function, and it is better to use functional components instead of class component.
First, you must use useEffect function for setState after AsyncStorage setItem:
const [asyncStorageItemSet, setAsyncStorageItemSet] = React.useState(false);
const [storageKey, setStorageKey] = React.useState('')
React.useEffect(() => {
AsyncStorage.getItem('#storage_Key').then(res => {
setStorageKey(res);
})
}, [asyncStorageItemSet])
and your return likes this:
<Button
onPress={storeData}
title="Store"
color="#841584"/>
<Text>{storageKey}</Text>
and storeData function looks like this:
const storeData = () => {
const value= "hello"
AsyncStorage.setItem('#storage_Key', value).then(res => {
setAsyncStorageItemSet(true)
})}
With functional components, broadly you want to
use the useState hook to create a variable/setter to hold the value you eventually get back from the promise.
use the useEffect hook to run the asynchronous process.
This means you will get at least 2 renders:
From before you have a value and
When you got the result
The first render the value will not be there.
If you haven't used the 2 hooks before, start by learning about them.
No, since the async functions are executed differently, the first instance of an asynchronous function does not return anything, in this way the render will return null which is worth a failure of the rendering of the component, that is maybe why we cannot directly call the Async function inside the render

Why doesn't useEffect directly support async callbacks or have separate parameters for the cleanup function?

I know I can't directly pass an async callback like this to useEffect
useEffect(async () => { // not supported, as this implicitly returns a Promise
const result = await axios(
'https://someurl',
);
setData(result.data);
});
as React expects nothing or a (cleanup) function callback as the first parameter for useEffect.
What I don't understand though: Is there any specific reason for this design choice? Why isn't there instead a signature like useEffect(callback, cleanup, dependencies) which would then allow me to directly pass in an async callback as first parameter, as the cleanup function could be easily passed in as second parameter?
What I don't understand though: Is there any specific reason for this
design choice?
One of the reasons that comes to mind is following. In react often when you return function from useEffect it does job like unsubscribing from things etc. and often you might need to access some variables from useEffect. For example:
useEffect(() => {
let cancelled = false;
fakeFetch(person).then(data => {
if (!cancelled) {
setData(data);
}
});
return () => {
cancelled = true;
}
}, [person])
With your design, you wouldn't be able to do above.

Understanding async dispatch actions using redux thunk

I was just going though the files that dispatches ACTIONS in a reactjs app and basically came across the following function::-
// When app inits
export const init = () => async dispatch => {
dispatch({ type: TYPES.SET_LOADING });
await dispatch(getConfig());
await dispatch(getGenres());
dispatch({ type: TYPES.REMOVE_LOADING });
};
I am a bit confused as to what the async is doing ahead of the dispatch , i am used to seeing normal vanilla javascript async functions like so:
anasyncfunc = async () => {
// write you're code here
}
But the above code confuses me a little. Can somebody please explain this to me.
A function which uses the await keyword must me marked with async which you have pointed out in your example
anasyncfunc = async () => {
// write you're code here
}
In this function we can now use await since it was marked with async.
In the case of the thunk, we are effectively creating an outer function called init which when called will return an anonymous function. This anonymous function will accept dispatch as an argument and will make use of the await keyword, and as such needs to be marked with the async keyword.
In short, we really are just creating a function which will want to use await and therefor must be marked with async.
I hope this clarifies it.

Why we use async before function in react

Sometimes we use async before the function. I want to know why and what is the proper use of async.
async remove(id) {
axios.delete('http://localhost:9022/users/delete/'+id)
.then(res => {
let updatedUsers = [...this.state.users].filter(i => i.id !== id);
this.setState({users: updatedUsers});
});
}
& what is the meaning of this
Users.propTypes = {
classes: PropTypes.object.isRequired,
};
An asynchronous function is a function which operates asynchronously
via the event loop, using an implicit Promise to return its result...
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function
Async functions basically allow us to have nicer syntax for anything that does an asynchronous operation (API call, DB query, timeout, etc...).
We you define a function as async, you gain access to the await keyword, which prevents you from having to deal with callback functions or promise chaining.
For example:
async function foo() {
let example = await apiQuery();
...
}
If you didn't specify a function as async, you would have to do it this way.
function foo() {
apiQuery().then((data) => console.log(data));
...
}
You can see the first example provides a more clear approach to dealing with async functions. Working with multiple async function calls can start to get messy without it.
As for your second question.
PropTypes are a way of telling other developers that your React component requires some external input (props) to work correctly. So in your case, the Users component requires a prop titled classes that is of the type Object
See more here - https://reactjs.org/docs/typechecking-with-proptypes.html

Resources