permalinkUsing the 'use client'
directive
When you do anything in your components that requires state they can't be rendered on the server.
This is because the server doesn't have access to the state of your app.
This is where the use client
directive comes in.
It allows you to tell your components that they should only be rendered on the client.
It has a weird syntax however which is a string at the top of the file just saying 'use client'
.
It's surprisingly difficult to produce this string with PureScript but here's how I do it:
permalinkCompile your PureScript with the --comments
flag
Here's an excerpt from my package.json
:
{
"scripts": {
"build:spago": "spago build --purs-args \"-c\""
}
}
This tells the compiler to leave any comments inside your code untouched.
permalinkUse a comment to produce the 'use client'
string
Here's an example of a component that uses the 'use client'
directive:
-- use client
module Container (default) where
import Prelude
import React.Basic.Hooks as React
import React.Basic (JSX, ReactComponent, fragment)
import React.Basic.Hooks (ReactChildren, reactChildrenToArray)
import Effect.Unsafe (unsafePerformEffect)
import React.Basic.DOM (text)
default :: ReactComponent { children :: ReactChildren JSX }
default = unsafePerformEffect $ React.reactComponentWithChildren "Container" \props -> React.do
let children = reactChildrenToArray props.children
state /\ setState <- React.useState 0
pure $ fragment [ children, text state ]
It's important to use unsafePerformEffect
here because Next.js will check for actual ReactComponent
s in the file.
It's perfectly fine to use unsafePerformEffect
at the top level of your files.
permalinkUse a webpack loader to transform the comment into the directive
Install it first:
npm install --save-dev string-replace-loader
module.exports = {
experimental: {appDir: true},
webpack: config => {
config.module.rules.push({
test: /index\.js$/,
loader: 'string-replace-loader',
options: {
search: '// use client',
replace: '"use client";'
}
},
{
test: /\.purs/, type: 'asset/source',
}
)
return config
}
}
There's the string-replace-loader which will replace the comment with the directive in all of our files PureScript files.
The good thing is that purs-ide leaves the comments alone, so you can still use it to develop your PureScript code.
Just make sure that you use npm run build:spago
and not spago build
to build your PureScript code.
use server