Skip to content

Commit

Permalink
docs: added cheatsheet for best practices (#2266)
Browse files Browse the repository at this point in the history
* docs: added cheatsheet for anti patterns

* docs:cleanup

* chore: another clickup and spacing update

* chore: Release 0.14.1 (#2264)

* 0.14.1

* 🐤

* fix: page, endpoint, q-data GET request (#2265)

* chore: release qwik-city 0.0.127 (#2269)

* chore: Add my stock investing website (#2268)

:)

* fix: signal rendering of classes (#2271)

fixes #2245

* docs: fix a typo (#2279)

* docs: Inline causes the clock to not show (#2283)

clock.css is not correctly loaded which causes the clock to not show.
Error: Cannot find module './clock.css?inline' or its corresponding type declarations.

* docs: Tutorial onError should be onRejected (#2284)

When using onError in the IDE as provided in the example it gives the following error:
Property 'onError' does not exist on type 'IntrinsicAttributes & ResourceProps<string[]>'

The solution says it should be onRejected

* fix: not silent error during rendering (#2297)

* fix: correctly handle draggable and spellcheck (#2299)

Co-authored-by: Jeremy Wickersheimer <jwickers@gmail.com>

* docs: right menu for Getting Started & Think Qwik (#2243)

* fix: dev server 302 error (#2300)

* feat: non-serializable response data dev error (#2305)

* docs: fix typo (#2302)

* docs: include vercel edge in the adaptors overview (#2292)

* fix(optimizer): missing args passed to wasm fallback (#2308)

* fix: textarea value rendering in SSR (#2309)

fixes #2235

* feat: better error reporting (#2312)

* fix: render toggle + signal (#2313)

fixes #2311

* feat: Link prefetch by default (#2314)

* fix: useContent menu lookup (#2315)

* docs: updated img-models url in showcase (#2320)

* fix: rendering of sibling component and mandatory key (#2321)

* feat: click-to-source  (#2217) (#2319)



Co-authored-by: Bruno Crosier <bruno.crosier@gmail.com>

* chore: 0.15.0 (#2330)

* fix: client redirect for trailing slash (#2333)

* fix: forceConsistentCasingInFileNames in starters (#2334)

* docs: fix typos and improve explanations (#2332)

* fix: click-to-component (#2335)

* docs: fix some typos and align explanations (#2331)

* release: qwik-city 0.0.128 (#2337)

* docs: fix build.preview (#2341)

* chore: add vite ecosystem scripts (#2349)

* docs: fix typo lifecycle (#2346)

* feat: add URLSearchParams to serializer (#2352)

* refactor: use class prop without casting to any (#2348)


Co-authored-by: langbamit <langbamit@gmail.com>

* feat: add to package.json when present in the ssr dir (#2354)

* docs: Add Qwind starter template to showcase (#2343)

* fix: detect and error on array holes (#2356)

* chore: remove className (#2310)

* fix: textarea vdom patching (#2357)

fixes #2344

* fix: update features (#2363)

* fix: jsx rule with fragment (#2364)

fixes #2177

* feat: Pre-fetch Link data on anchor focus (#2358)

* fix: useClientEffect() in empty components (#2365)

fixes #1955
fixes #2329
fixes #1062
fixes #1413
fixes #1446

* chore: release 0.15.1 (#2366)

* docs: improve styling docs (#2367)

* fix: make array hole test more readable (#2369)

* 0.15.2 (#2371)

* docs: fix typo (#2372)

* docs: removed unnecessary fragments (#2361)

* docs: Add Guide On Using Map Functions In JSX (#2373)

* docs: remove async from component$ overview (#2377)

* feat: add config for dev inspector (#2375)

* docs(qwik-v-react): fix array key consistency in docs (#2383)

Qwik array map in qwik vs. react did not have key even though in rendering portion of docs it says
key is required

* fix(vite): module side effect (#2387)

* feat: detect invalid HTML (#2389)

* docs: link accessibility (#2386)

* feat: standardize params/query api (#2385)

Co-Authored-By: Tran Thien Khiem <20198928+tuoitrevohoc@users.noreply.github.com>

* docs(contributing): Add install note for wasm-pack (#2390)

To avoid running into unexpected `wasm-pack` failures when doing full build, adds note to Contributing docs about installation of `wasm-pack`, linking to site showing installation command for each platform.

* docs: update anti pattern to best practice

Co-authored-by: Manu MA <manu.mtza@gmail.com>
Co-authored-by: Adam Bradley <adamdbradley@users.noreply.github.com>
Co-authored-by: Shih-Min Lee <ssmlee04@gmail.com>
Co-authored-by: Tejas Kumar <tejas+lol@tejas.qa>
Co-authored-by: Bryan Hannes <31400961+bryanhannes@users.noreply.github.com>
Co-authored-by: Jeremy Wickersheimer <jwickers@gmail.com>
Co-authored-by: Forresst <forresst17@gmail.com>
Co-authored-by: Mhmdrz_a <mr.ala72@gmail.com>
Co-authored-by: Shai Reznik <shairez@users.noreply.github.com>
Co-authored-by: Bruno Crosier <bruno.crosier@gmail.com>
Co-authored-by: Alberto Mijares <almilo@users.noreply.github.com>
Co-authored-by: Uther Pally <43192714+langbamit@users.noreply.github.com>
Co-authored-by: langbamit <langbamit@gmail.com>
Co-authored-by: Wim Holvoet <holvoetwim@gmail.com>
Co-authored-by: prototypa <54446028+prototypa@users.noreply.github.com>
Co-authored-by: Glenn Becker <nnelgxorz@gmail.com>
Co-authored-by: Wout Mertens <Wout.Mertens@gmail.com>
Co-authored-by: Saikat Das <saikatdas0790@gmail.com>
Co-authored-by: Sai Srikar Dumpeti <80447788+the-r3aper7@users.noreply.github.com>
Co-authored-by: Justin Scopelleti <38704268+Kesmek@users.noreply.github.com>
Co-authored-by: roman zanettin <zanettin@users.noreply.github.com>
Co-authored-by: jweb89 <62513031+jweb89@users.noreply.github.com>
Co-authored-by: Tran Thien Khiem <20198928+tuoitrevohoc@users.noreply.github.com>
Co-authored-by: machineloop <3682072+machineloop@users.noreply.github.com>
  • Loading branch information
1 parent b1cae93 commit eec2096
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 1 deletion.
107 changes: 107 additions & 0 deletions packages/docs/src/routes/docs/cheat/best-practices/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
---
title: Best Practices
contributors:
- mhevery
---

# No-Hydration Tips
## Don't register events eagerly with `useClientEffect$()`
> ⚠ Use `useClientEffect$()` with caution ⚠
Instead => `useOn()` methods

**Best Practice**:

```typescript!
useClientEffect$(()=> {
const listener = (event)=> {
const mouseEvent = event as MouseEvent
console.log(mouseEvent.x, mouseEvent.y);
}
document.addEventListener('mousemove', listener);
return ()=> {document.removeEventListener(listener)}
})
```

**Why is above a problem**:
This forces more javascript to eagerly load, rather than be surgically reactive to user events. More upfront javascript => slower app performance.

It also requires you, the developer, to stay more aware of the server/client relationship (there's a reason you reached for `use >Client< Effect` after all).

While that's sometimes necessary, it should be the job of the framework to keep you from having to worry about it as much as possible.

Not to mention it requires the extra effort for you to manually clean up the listener.

**Do this instead**:

```typescript!
useOnDocument('mousemove', $((event)=> {
const mouseEvent = event as MouseEvent;
console.log(mouseEvent.x, mouseEvent.y)
// No manual clean up required!
}))
```

> NOTE: Similar hooks exist for window and individual components.
> `window` -> `useOnWindow` , component -> `useOn`
> * [useOn / useDocument / useWindow docs](https://qwik.builder.io/tutorial/hooks/use-on/)
> * [Example](https://qwik.builder.io/tutorial/hooks/use-on/#example)
> * [Tutorial](https://qwik.builder.io/tutorial/events/programmatic/)
----



## Don't rely on `window` to get the location

Instead => `useLocation()`

**Best Practice**:

```typescript!
useClientEffect$(()=> {
if (window.location.href).includes('foo') {
//... do the thing
}
})
//OR
//(in the root of a component)
if (typeof window !== "undefined") {
const queryParams = new URLSearchParams(window.location.search);
const query: Record<string, string> = {};
queryParams.forEach((value, key) => {
query[key] = value;
})
doTheThing(query);
}
```

**Why is above a problem**:
Many, many things you'll do in response to location information can easily be done on the initial render on the server, and will result in pure HTML with no JS overhead.

If you force that logic to instead run on the client side, it introduces more upfront JS & causes an eager load.


When using the `if typeof window !== "undefined"` pattern you'll soon find it will simply skip that code. It will run one time on the server and skip the code block because window will always be undefined on the server. You're used to code running twice. Qwik doesn't need to! 😎

**Do this instead**:
```typescript!
const location = useLocation();
if (location.href.includes('foo')) {
// Do the thing
}
//OR
doTheThing(location.query);
```


## EXCEPTION
When doing SSG for pure static files, this is a necessary evil. The server won't have current location information when the server generates the files at build time.

But be mindful! If the information you need (e.g., query parameters) won't be necessary until some sort of user event, include the check in your event handling code instead to avoid the eager loading of JS.

> See: [useLocation() Docs](https://qwik.builder.io/qwikcity/api/#uselocation)
2 changes: 1 addition & 1 deletion packages/docs/src/routes/docs/docs.css
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
font-size: 42px;
font-weight: 800;
scroll-margin-top: var(--scroll-margin-top);
margin-top: 70px;
margin-top: 45px;
}

.docs article h3 {
Expand Down
1 change: 1 addition & 0 deletions packages/docs/src/routes/docs/menu.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

- [Qwik vs React](cheat/qwik-react/index.mdx)
- [Serialization](cheat/serialization/index.mdx)
- [Best Practices](cheat/best-practices/index.mdx)

## Concepts

Expand Down

0 comments on commit eec2096

Please sign in to comment.