Using Async await in react component
I think you need more about async/await
in JS.
An async function
always return a promise.
So x
in Wrapper
is a promise. Because you don't use await/async
.
It should be like this.
async Wrapper = (body) => {
try{
let x = await this.Send(body); // <-- missing await here
return x;
}catch(e){console.log(e)}
}
But then, the code in render
doesn't work. because this.Wrapper()
now returns a promise. -> returnData is a promise
. And the render
method can't be async function :)
render(props) {
//...
const returnData = this.Wrapper(jsonBody) // <-- returnData here is a promise.
//...
So to make things work.
You have to use state
. Call the this.Wrapper
in componentDidMount
or componentDidUpdate
. For example:
constructor() {
// ...
this.state = { returnData: null }
}
async componentDidMount() {
const returnData = await this.Post(...); // Using await to get the result of async func
this.setState({ returnData });
}
async Post(body) {
try{
const options = {
method: 'POST',
uri: 'XXXXXXXXXXXXXXXXXXXX',
body: body
}
return rp(options); // define await then return is unnecessary
}catch(e){console.warn(e)}
}
render() {
const { returnData } = this.state;
// ... Do the rest
}
Scottt
Updated on July 20, 2022Comments
-
Scottt almost 2 years
So I've created a component that shoots off post requests with props that I provide.
Although I'm familiar with Async await I for some reason can't seem to get this to return the actual value of the fulfilled promise and instead just get pending.
I've tried wrapping with more functions as I understand the promise is not being resolved.
I feel like I'm missing something.
A sample of my code below
export default class PostController extends React.Component { constructor(props) { super(props) } Wrapper = (body) => { try{ let x = this.Send(body); return x; console.log(x) }catch(e){console.log(e)} } Send = async (body) => { try{ let data = await this.Post(body); return data; }catch(e){console.warn(e)} } Post = async (body) => { try{ const options = { method: 'POST', uri: 'XXXXXXXXXXXXXXXXXXXX', body: body } const data = await rp(options); return data; }catch(e){console.warn(e)} } render(props) { let jsonBody = JSON.stringify(this.props.data) const returnData = this.Wrapper(jsonBody) console.log(returnData) return( <div> {(!this.props.data.pw) ? 'Retrieved Password: ' + returnData.message : 'Generated PassWord!:' + returnData.message } </div> ) }
}
-
Scottt about 5 yearsExcellent! Didn't realize could use componentdidmount like that! I have a lot to learn!
-
Tan Dat about 5 years@Scottt: if the answer is what you need. go mark it as correct answer!
-
Sebastian Nielsen almost 3 yearsBut won't this unnecessarily fetch posts for each mount? Which will result in very inefficient code.
-
Suisse almost 3 yearsUnexpected reserved word 'await'. I am using it in async componentDidMount() strange!
-
Tan Dat almost 3 years@Suisse maybe you're using old version that does not support async await?
-
Suisse almost 3 years@TanDat older version of react? O_O I used npx create-react-app my-app - don't think that is an old version there. strange.