Product design

Duolingo: connect understanding an answer with practicing again

Duolingo is a language-learning app for everyday learners. Answer explanations help with the question just completed, while practice options let people return deliberately to weaker areas and plan their next session.

Break down the problem and try your own design and implementation first. Then explore the reasoning to check states, edge cases, trade-offs, and ways to test your approach. The guide offers a reasoning path, not a complete implementation.

01
FRONTEND EXERCISE

Build a small answer-explanation component

Suppose you are building a language-practice page. Users can expand an explanation after answering, but a new answer must not inherit the previous answer’s expanded state. Implement a small AnswerFeedback component.

  1. Given data: It receives answerId (the identifier for one response), the user’s answer, the correct answer, and explanation (text or null for no explanation). Submitting the same question again also creates a new identifier. Data does not change under the same identifier, and no network request is needed.
  2. Display rules: An answer starts collapsed. If explanation text exists, show View explanation, then Hide when expanded. With no explanation, show “No explanation available” and no expansion button. A different answerId from the parent must collapse the panel, even for the same question. An ordinary rerender with the same identifier preserves the expanded state. Buttons must work with a keyboard and expose their current expanded state.
  3. Check: Expand answer A; rerendering the same A keeps it expanded. Replace it with B: the panel collapses and shows B’s answer. Replace it with C, whose explanation is null: neither A’s nor B’s explanation appears, and there is no expansion button.
  4. Deliver: Submit the component, a runnable example and a short explanation of who owns the state. Check the stated sequence.
Explore the reasoning
  1. Separate answer data supplied by the parent from expansion state owned by the component. Use one answer’s identity to define that state’s lifetime.

  2. Trace A expanding, A rerendering and B replacing it. Check when state should survive and when it should reset.

  3. Check C with no explanation: visible information and available actions must agree. Use a native button and an expanded-state attribute to check keyboard interaction.