Home > Software design >  How can I display the result of a promise on a webpage in a react export
How can I display the result of a promise on a webpage in a react export

Time:10-14

All articles I have read on promises show examples with console.log - I am using AWS Athena and want to display the result on the webpage in my React export. The react export does not allow the use of .then. So I need to resolve the promise to an external variable.

client is a aws athena client which returns a promise I need to resolve.

async function getResult(){
try {
    return await client.send(command);
  } catch (error) {
    return error.message;
  }
}

export default getResult()

I want to display the result in App.js

render() 
{
return (
   { athena }
)

It displays in the console but not on the webpage as the page is loaded before the variable is resolved.

More complete example of App.js

import athena from './athena';
class App extends Component {
render() 
  {
    let athena_result = athena.then(function(result) {
      console.log(result)
    }
    )

  return ( athena_result )

Causes Error

Error: Objects are not valid as a React child (found: [object Promise])    

CodePudding user response:

The render method of all React components is to be considered a pure, synchronous function. In other words, there should be no side effects, and no asynchronous logic. The error Error: Objects are not valid as a React child (found: [object Promise]) is the component attempting to render the Promise object.

Use the React component lifecycle for issuing side-effects. componentDidMount for any effects when the component mounts.

class App extends Component {
  state = {
    athena: null,
  }

  componentDidMount() {
    athena.then(result => this.setState({ athena: result }));
  }

  render() {
    const { athena } = this.state;
    return athena;
  }
}

If you needed to issue side-effects later after the component is mounted, then componentDidUpdate is the lifecycle method to use.

Class components are still valid and there's no plan to remove them any time soon, but function components are really the way going forward. Here's an example function component version of the code above.

const App = () => {
  const [athenaVal, setAthenaVAl] = React.useState(null);

  React.useEffect(() => {
    athena.then(result => setAthenaVAl(result));
  }, []); // <-- empty dependency array -> on mount/initial render only

  return athenaVal;
}

The code is a little simpler. You can read more about React hooks if you like.

CodePudding user response:

You can use a state, and just set the state to the response's value when it's done:

const Component = () => {
  const [athena, setAthena] = useState(""); // Create a state with an empty string as initial value

  // Send a request and on success, set the state to the response's body, and on fall set the state to the error message
  useEffect(() => client.send(command).then((response) => setAthena(response.data)).catch((error) => setAthena(error.message)), []);

  return <>{athena}</>;
};
  • Related