Here's a code review comment I've received more than once, and, honestly, written more than once:
Change this to use
useMemo.
It's correct. It's fast. The PR gets merged. And the junior who wrote it learns exactly one thing: that a senior person wanted useMemo there.
Next week, they'll ask again. Or worse, they'll start adding useMemo everywhere.
The banking model of code review
In Pedagogy of the Oppressed (1968), the Brazilian educator Paulo Freire described what he called the banking model of education. The teacher knows; the student doesn't. The teacher makes "deposits" of knowledge, and the student's job is to receive, store and repeat them.
Freire's problem with it wasn't only that it's boring. It's that it produces people who can follow instructions but can't think through new problems, and who learn that knowledge always comes from above.
A lot of code review works exactly like a bank:
- The reviewer has the answer.
- The comment states the fix.
- The author applies it.
- Nobody talks about why.
It scales badly. Seniors become bottlenecks, juniors stay dependent, and the team's knowledge lives in a few people's heads.
Problem-posing review
Freire's alternative was problem-posing education: instead of handing over answers, the teacher poses real problems, and teacher and student work through them together in dialogue. Both learn something. The student builds the ability to reason, not just a memory of the right answer.
In a code review, that shift can be surprisingly small:
| Banking comment | Problem-posing comment |
|---|---|
"Change this to use useMemo." | "This list re-renders on every keystroke. What do you think is causing it? Happy to pair if you want to dig in." |
| "Wrong. Handle the error." | "What should the user see if this request fails?" |
| "Don't put this in the component." | "If we need this same logic in the checkout page next month, where would you want it to live?" |
| "Use a Map here." | "This lookup runs inside a loop over every order. How does that scale with 10,000 orders?" |
The questions aren't a trick to avoid giving answers. If the author is stuck, give the answer, and explain it. The point is that the first move is to invite their reasoning, not to replace it.
Five habits I try to practice
1. Explain the why, every time.
If you do write a direct fix, add one sentence about the reason. "Use useMemo here because this sort runs on every render and the list can be large." That sentence is the part they'll remember.
2. Ask about consequences, not syntax.
Linters handle syntax. Humans are good at asking about users, failures, edge cases and the future. "What happens if…" is the most useful phrase in review.
3. Mark the weight of each comment.
Freire insisted on dialogue between equals, and power makes that hard. Juniors often treat every comment as an order. Labels help: nit:, suggestion:, question:, blocking:. They make clear what's open for discussion.
4. Let the author teach you.
Dialogue goes both ways. Ask why they chose an approach before suggesting another. Sometimes they had a reason you didn't see. Saying "oh, I didn't know that, thanks" in a review is one of the most powerful things a senior can do for a team's culture.
5. Move long threads to a conversation.
After three back-and-forths, a 15-minute pairing session teaches more than ten more comments. Write the conclusion back in the PR so the knowledge stays.
Critical consciousness, in software
Freire had another idea that matters for engineers: conscientização, usually translated as critical consciousness. Education shouldn't only teach skills; it should help people understand the world they act in and question its effects.
In our work, that means mentoring isn't just about clean code. It's also about asking, together:
- Who might this feature exclude?
- What data are we collecting, and do we need it?
- What happens to the people on the other side of this screen if it fails?
A junior who learns to ask those questions is worth more to a team than one who memorized every React hook.
What teaching kids taught me about teaching devs
Before and alongside my engineering work, I've taught STEAM workshops, mixing science, technology, art and math. The biggest lesson from those rooms is the same one Freire wrote about: people learn most when they're working on a problem that's real to them, and when someone asks them a good question at the right moment, instead of telling them the answer.
Developers are no different. The best mentors I've had rarely gave me the fix. They asked one question that made me see the problem differently, then let me find the way.
Seniority is how much others grow around you
There's a version of "senior" that means "the person who knows the answers." And there's a better one: the person whose team keeps getting better at finding answers without them.
Code review is where that happens, a few comments at a time. We can use it to make deposits, or to start a dialogue.
This piece comes from an essay I wrote on STEAM education, complexity and critical pedagogy during my master's. It's part of my series on the human side of building software.
What's the best review comment you ever received? I'd love to collect a few in the comments.
References
- Freire, Paulo. Pedagogy of the Oppressed. 1968 (first English edition 1970).
- Morin, Edgar. Introducción al pensamiento complejo. Gedisa, 1994.