Search⌘ K
AI Features

Getting a Sentiment for a Review

Explore how to build a React component that sends review text to an AI service for sentiment analysis, then displays the result with proper loading and error handling. Understand managing asynchronous state and integrating AI responses safely in a UI.

The previous lesson connected React to the page and rendered fixed text. This one adds the first real piece: a button, a request, and a result that depends on what comes back rather than something already known ahead of time.

What this component does

A review is shown on the page. Clicking a button sends that review to an endpoint and asks for its sentiment, one of positive, neutral, or negative. Once the answer arrives, it's shown as a badge next to the review. A second button moves to the next review in a small curated list, so the same flow can be tried against more than one piece of text.

The state this needs

Three pieces of state, each answering a different question.

State

Answers

current

Which review is showing right now

sentiment

What the last request returned, if anything

loading

Whether a request is currently in progress

sentiment starts as null and only gets a value once a request finishes. loading is what the button reads to decide whether to show "Checking..." or disable itself, so two requests can't be sent at once from the same click.

1.

Why does checkSentiment reset sentiment to null at the very start, before the request has even been sent?

Show Answer
Did you find this helpful?

The request

The request is sent to a fixed address, /api/ai/complete, the same address used throughout this course. What sits behind that address, and which service actually produces the sentiment, is outside what this component needs to know. All it does is send the review's text inside a prompt, and read whatever comes back.

const res = await fetch("/api/ai/complete", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
prompt: `Read this review and return one word: positive, neutral, or negative. Return nothing else.\n\n"${current.text}"`,
}),
});

The prompt itself is worth noticing: it names the three allowed words directly, the same practice covered in Module 3's prompt lessons. Naming the options here is what makes the result usable as a badge at all, rather than some open-ended description of the review.

Handling what comes back

A request can succeed or fail, and the component accounts for both.

try {
const res = await fetch("/api/ai/complete", { /* ... */ });
const data = await res.json();
setSentiment(data.result.toLowerCase());
} catch (err) {
setSentiment("error");
} finally {
setLoading(false);
}

If the request fails for any reason, sentiment becomes the string "error" rather than being left empty, which gives the interface something concrete to show instead of quietly doing nothing. loading is set back to false in the finally block, so it turns off whether the request succeeded or not.

Try it yourself

Please click the “Run” button to start. Once the commands are executed for setup, open a new terminal using the “+” button and type cd /usercode/sentiment-val && npm run dev to run the app.

Note: Make sure to add your API key in the .env file and select the relevant provider.

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Sentiment Check</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.jsx"></script>
  </body>
</html>
A component that sends a review to an endpoint and displays the sentiment it returns, with a second button to try another review