mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-28 17:57:48 +02:00
docs(advanced-guides): adding a bit more context to SSG useIsBrowser
documentation to promote use of <BrowserOnly>
This commit is contained in:
parent
6206a99c10
commit
d53136d59c
1 changed files with 52 additions and 20 deletions
|
@ -190,8 +190,7 @@ The first client-side render output (in the browser) **must be exactly the same*
|
|||
Usage example:
|
||||
|
||||
```jsx
|
||||
import React from // useState,
|
||||
// useEffect
|
||||
import React from // useEffect // useState,
|
||||
'react';
|
||||
import useIsBrowser from '@docusaurus/useIsBrowser';
|
||||
|
||||
|
@ -211,24 +210,6 @@ const MyComponent = () => {
|
|||
? window.location.href
|
||||
: isFetchingLocationMessage;
|
||||
|
||||
/*
|
||||
const [isFetchingLocation, setIsFetchingLocation] = useState(
|
||||
location === isFetchingLocationMessage
|
||||
)
|
||||
// Please note that `isFetchingLocation` initial value will be `true`
|
||||
// even though window is actually defined
|
||||
// because component has actually rendered once before hydration
|
||||
// subsequent renders will not update the useState
|
||||
// and may cause issues with business logic
|
||||
|
||||
// Do this instead
|
||||
const [isFetchingLocation, setIsFetchingLocation] = useState(true)
|
||||
|
||||
useEffect(() => {
|
||||
setIsFetchingLocation(location === isFetchingLocationMessage)
|
||||
}, [isBrowser])
|
||||
*/
|
||||
|
||||
// highlight-end
|
||||
return (
|
||||
<div>
|
||||
|
@ -242,6 +223,57 @@ const MyComponent = () => {
|
|||
};
|
||||
```
|
||||
|
||||
:::caution If your business logic in the component relies on browser specifics to be functional at all, we recommend using [`<BrowserOnly>`](../docusaurus-core.mdx#browseronly). The following example will cause business logic issues when used with `useIsBrowser`:
|
||||
|
||||
```jsx
|
||||
import React, {useState} from 'react';
|
||||
import useIsBrowser from '@docusaurus/useIsBrowser';
|
||||
|
||||
const isFetchingLocationMessage = 'fetching location...';
|
||||
|
||||
const MyComponent = () => {
|
||||
const isBrowser = useIsBrowser();
|
||||
const location = isBrowser ? window.location.href : isFetchingLocationMessage;
|
||||
// highlight-start
|
||||
const [isFetchingLocation, setIsFetchingLocation] = useState(
|
||||
location === isFetchingLocationMessage,
|
||||
);
|
||||
|
||||
// highlight-end
|
||||
return (
|
||||
<div>
|
||||
{/*
|
||||
This will always print true and will not update.
|
||||
Component already rendered once and useState referenced the initial value as `true`
|
||||
*/}
|
||||
{isFetchingLocation}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
```
|
||||
|
||||
To solve this, you can add a `useEffect` to run when hydration has completed:
|
||||
|
||||
```js
|
||||
useEffect(() => {
|
||||
setIsFetchingLocation(location === isFetchingLocationMessage);
|
||||
}, [isBrowser]);
|
||||
```
|
||||
|
||||
Or use [`<BrowserOnly>`](../docusaurus-core.mdx#browseronly):
|
||||
|
||||
```
|
||||
const ParentComponent = () => {
|
||||
return (
|
||||
<BrowserOnly fallback={<div>Loading...</div>}>
|
||||
{() => <MyComponent />}
|
||||
</BrowserOnly>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
### `useEffect` {#useeffect}
|
||||
|
||||
Lastly, you can put your logic in `useEffect()` to delay its execution until after first CSR. This is most appropriate if you are only performing side-effects but don't _get_ data from the client state.
|
||||
|
|
Loading…
Add table
Reference in a new issue