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 ReactComponents 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-loadermodule.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