@derbyjs/derby-react enables React components to be integrated with DerbyJS apps and/or Racer models:
- React component state that's two-way synced with Racer model data
- Derby helper to render a React component inside a Derby component, with automatic cleanup
React version requirements:
useRacerStatesupports React versions 16 and higher.- The Derby
renderReactComponenthelper requires React 18 and higher due to usingreactDom.createRoot, which was introduced in React 18.
This example uses a Derby component with a directory containing index.html and index.tsx.
<!-- index.html --><index:><h2>Derby controls</h2><div><div>Message: <inputvalue="{{message}}"></div><div>Counter: <span>{{counter}}</span><buttonon-click="model.increment('counter', 1)">Increment</button></div></div><h2>React controls</h2><divas="reactAppContainer"></div>// index.tsximport{Component}from'derby';import{renderReactComponent,useRacerState}from'@derbyjs/derby-react';importtype{Model}from'racer';classReactDerbyExampleextendsComponent{staticview={file: __dirname,is: 'derby-react-example',};declarereactContainer: HTMLElement;create(){renderReactComponent(this,this.reactContainer,<ReactControlsmodel={this.model}/>);}}functionReactControls({ model }: {model: Model}){// useRacerState accepts a Racer model scoped to the desired value's pathconst$message=model.at<string>('message');const[message,setMessage]=useRacerState($message);const$counter=model.at<number>('counter');const[counter]=useRacerState($counter,0);return(<>{/* State can be updated with a React state setter... */}<div>
Message: <inputvalue={message}onChange={(e)=>setMessage(e.target.value)}/></div>{/* ...or state can also be updated with model methods. */}<div>
Counter: <span>{counter}</span>{' '}<buttononClick={()=>$counter.increment()}>Increment</button></div></>);}