Kent C. Dodds
Don't Solve Problems
Eliminate Them
Let's wake up
Your brian needs this 🧠
What this talk is
- Problems, Solutions, and Trade-offs
- Solving < Eliminating < Avoiding
Don't Solve Problems. Eliminate Them.
What this talk is not
- Code examples
- 100% about code
- Domain-specific
Don't Solve Problems. Eliminate Them.
Problem Tree
Problems lead to solutions lead to problems
You are a problem solver
You are a problem seeker
Storytime
"Possibly the most common error of a smart engineer is to optimize the thing that should not exist" – Elon Musk
It's better to avoid problems than to solve them.
Avoidance Problem Tree
Unavoidable Problems
You should be a problem eliminator
Solutions hold you captive
Problems "solved"
- Exhaust
- Stopping
- Car Fires
- Sustainability
Problems Eliminated
(mostly)
- Exhaust
- Stopping
- Car Fires
- Sustainability
Elimination Problem Tree
Tesla's Giga Casting
Problem Elimination
In software
React and Code Reuse
<Chart>
{render => props}</Chart> ?
withChart(HOC) ?
From "Thinking in React Hooks" by Amelia Wattenberge
wattenberger.com/blog/react-hooks
Functions!
What kentcdodds.com is
General stats
- 27k lines of code
- PM, Designer, Illustrator, UI Dev + me + some other contributors (/credits)
Nested Routing
Seamless Client/Server
Web Foundation
Simple Mutations
CSS Loading *and* Unloading
Client
Server
// look mah! No useEffect, isLoading, or isError!
export async function loader({ request }: DataFunctionArgs) {
return json({ teamsInOrder: shuffle(teams) })
}
export default function NewAccount() {
const data = useLoaderData<typeof loader>()
return (
// some UI stuff...
<fieldset className="contents">
<legend className="sr-only">Team</legend>
{data.teamsInOrder.map(teamOption => (
<TeamOption
key={teamOption}
team={teamOption}
error={actionData?.errors.team}
selected={formValues.team === teamOption}
/>
))}
</fieldset>
// more UI stuff
)
}
// note filtering out the stuff we don't need and the declarative error handling
export async function loader({ params, request }: DataFunctionArgs) {
// getSeasonListItems hits the simplecast API and filters out
// all the extra stuff we don't need for this route
const seasons = await getSeasonListItems({ request })
const seasonNumber = Number(params.season)
const season = seasons.find(s => s.seasonNumber === seasonNumber)
if (!season) {
throw new Response(`No season for ${params.season}`, { status: 404 })
}
return json(
{ season },
{
headers: {
'Cache-Control': 'public, max-age=600',
},
},
)
}
export default function ChatsSeason() {
const { season } = useLoaderData<typeof loader>() // <-- autocompleted
return <stuff />
}
export function ErrorBoundary() {
return (
<GeneralErrorBoundary
statusHandlers={{
404: ({ params }) => (
<Grid nested className="mt-3">
<div className="col-span-full md:col-span-5">
<H3>{`Season not found`}</H3>
<Paragraph>{`Are you sure ${
params.season ? `season ${params.season}` : 'this season'
} exists?`}</Paragraph>
</div>
<div className="md:col-span-start-6 col-span-full md:col-span-5">
<MissingSomething className="rounded-lg" aspectRatio="3:4" />
</div>
</Grid>
),
}}
/>
)
}
- fetch Request/Response
- <Form />
- <link rel="modulepreload" />
- <link rel="prefetch" as="fetch" />
Web Foundation
import type { LinksFunction } from 'remix'
import aboutStyles from '~/styles/routes/about.css'
export const links: LinksFunction = () => {
return [{ rel: 'stylesheet', href: aboutStyles }]
}
export default function AboutScreen() {
return <stuff />
}
CSS Loading *and* Unloading
Simple Mutations
- Loaders run in parallel
- Remix loads only what's needed
- Mutations trigger invalidation of all loaders
- Context for shared UI state & Remix for shared server state
- No <Layout /> component
/
:userId
users/
Nested Routing
&
Trade-offs
Eliminate big problems in exchange for smaller problems.
Conclusion
Solving
< Eliminating
< Avoiding
If you can't avoid the problem, try to eliminate it by changing your approach.
And only if that fails, solve the problem.
Let's make the world better
Thank you!
Don't Solve Problems, Eliminate Them.
By Kent C. Dodds
Don't Solve Problems, Eliminate Them.
Humans are natural problem solvers and we're good enough at it that we've survived over the centuries and become the dominant species of the planet. Because we're so good at it, we sometimes become problem seekers too–looking for problems we can solve. Those who most successfully accomplish their goals are the problem eliminators. Let's talk about the distinction between solving and eliminating problems with examples from inside and outside the coding world.
- 2,726