Jump to content

Recommended Posts

Posted (edited)

I have put together a example repository on how to use React with Redux and Typescript as UI (CEF). I was looking for something like this and the guides I could find felt outdated, not using current Rage APIs etc.

https://github.com/Raademar/rage-react-starter

 

Sending data from the Client to the UI (CEF)

this.browser = mp.browsers.new("package://cef/index.html#");
this.browser.execute( `window.store.dispatch({type: "ADD", payload: ${data}})`)

 

In order for the Redux store to be in the window scope we assign it like this in our root index.tsx

import store from "./store"
window["store"] = store

 

After this point we're on "normal" React roads again.

import { useAppSelector, useAppDispatch } from "../../store/hooks"
const texts = useAppSelector(state => state.text.texts)
const dispatch = useAppDispatch()

const handleSubmit = () => {
    dispatch({ type: "ADD", payload: "Cool input here" })
}

<div>
    {texts.map((text, index) => (
        <p key={index}>{text}</p>
    ))}
</div>

 

Sending data from the UI to the Client and Server

// React
const handleSubmit = () => {
    mp.trigger("CallServerEvent", "Login", JSON.stringify(loginInfo))
}
<form onSubmit={handleSubmit}>
...
</form>

// Client
mp.events.add({
    "CallServerEvent": (event: string, data: string) => {
        mp.events.callRemote(event, data);
    },
    ...
)}

// Server
mp.events.add({
    "Login": (player: PlayerMp, data: string) => {
        ... Handle login
    },
})

Handling routing

On the UI side we use React-Router with the HashRouter

import { HashRouter, Route, Switch } from "react-router-dom"
import { LoginScreen, CharacterSelection } from "./pages"

const Routes = () => {
	return (
		<HashRouter>
			<Switch>
				<Route path="/" exact component={HUD} />
				<Route path="/login" component={LoginScreen} />
				<Route path="/characterselection" component={CharacterSelection} />
			</Switch>
		</HashRouter>
	)
}

 

The routing is controlled from the Server/Client side

const path = `location.hash = "#${url}"`;
this.browser.execute(path);

 

Building and bundling

This example uses Tailwind for styling (Login page) and included are the minimum required setup to use Tailwind with React.

This is not needed and can be replaced with any other styling solution. Craco can also be removed if Tailwind is not used.

Craco

The react-scripts for start, build and test are replaced by craco to allow for postcss handling.

"start": "craco start", "build": "craco build", "test": "craco test",

Gulp

This example uses Gulp to bundle the built Javascript files to inline Javascript located in the build/index.html

Example on how I handle bundling and then moving the build folder to the right location.

// package.json in RAGE.mp server-files root
"gulp": "cd app/react-cef && npx gulp", 
"move-cef": "cp -r app/react-cef/build client_packages/cef/"

 

Edited by Raademar
Formating
  • Like 4
  • 1 month later...
  • 1 year later...
Posted

When trying npm run start, it starts croco, then :

An error is raised because mp is not included inside the node_modules,

mp.trigger("cMisc-CallServerEvent", "sLogin-Login", JSON.stringify(loginInfo))

- Is that normal that you have client code inside CEF ?

- How do I add mp dependency to a react project ?

  • 1 month later...
Posted (edited)
On 7/4/2021 at 5:45 PM, Raademar said:

Sending data from the Client to the UI (CEF)

this.browser = mp.browsers.new("package://cef/index.html#");
this.browser.execute( `window.store.dispatch({type: "ADD", payload: ${data}})`)

 

You have example at begining. Bind store reference to window.store if not already.

Edited by Kopra
  • 8 months later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...