Skip to content

Commit a9454fe

Browse files
AlainaFaisaljounicaalador
authored
Document how to wrap a field React component into Flow component (#3600)
* Update PR check configs from master * Initial Draft * Initial Draft 2 * Update articles/flow/integrations/react.adoc Co-authored-by: caalador <[email protected]> * Update articles/flow/integrations/react.adoc Co-authored-by: caalador <[email protected]> * Update articles/flow/integrations/react.adoc Co-authored-by: caalador <[email protected]> * Update articles/flow/integrations/react.adoc Co-authored-by: caalador <[email protected]> * Update articles/flow/integrations/react.adoc Co-authored-by: caalador <[email protected]> * Update articles/flow/integrations/react.adoc Co-authored-by: caalador <[email protected]> * Update articles/flow/integrations/react.adoc Co-authored-by: caalador <[email protected]> * Delete .github/workflows/alex.yml * Update articles/flow/integrations/react.adoc Co-authored-by: caalador <[email protected]> * Update articles/flow/integrations/react.adoc Co-authored-by: caalador <[email protected]> * Update articles/flow/integrations/react.adoc Co-authored-by: caalador <[email protected]> --------- Co-authored-by: Jouni Koivuviita <[email protected]> Co-authored-by: caalador <[email protected]>
1 parent 5103b9a commit a9454fe

File tree

1 file changed

+81
-0
lines changed

1 file changed

+81
-0
lines changed

articles/flow/integrations/react.adoc

+81
Original file line numberDiff line numberDiff line change
@@ -208,3 +208,84 @@ class ReactRouterLayoutElement extends ReactAdapterElement {
208208
209209
customElements.define('react-router-layout', ReactRouterLayoutElement);
210210
----
211+
212+
[[wrap-react-component]]
213+
== Wrapping a React Component Into a Flow Component
214+
215+
When integrating React components into Vaadin applications, one common requirement is to enable these components to participate in Vaadin's data binding and form handling.
216+
This can be accomplished by wrapping the React component in a Vaadin component that extends `AbstractSinglePropertyField`.
217+
This allows the React component to be used like any other field in Vaadin, making it compatible with the `Binder` API.
218+
219+
This integration process involves two main parts:
220+
- creating a Java class for the server-side adapter component
221+
- developing a client-side adapter using TypeScript and React.
222+
Next this process is demonstrated using a simple React text input component as an example.
223+
224+
=== Example Implementation:
225+
226+
=== Create the Client-Side React Component
227+
First, define your React component. For this example, assume a simple text input component.
228+
[source,jsx]
229+
----
230+
// File: frontend/react-text-input.tsx
231+
232+
import React, { useState } from 'react';
233+
import {ReactAdapterElement, type RenderHooks} from "Frontend/generated/flow/ReactAdapter";
234+
235+
class ReactTextInputElement extends ReactAdapterElement {
236+
constructor() {
237+
super();
238+
}
239+
240+
protected override render(hooks: RenderHooks): React.ReactElement | null {
241+
const [value, setValue] = hooks.useState<string>("value");
242+
243+
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
244+
setValue(event.target.value);
245+
this.dispatchEvent(new CustomEvent('value-changed', { detail: { value: event.target.value } }));
246+
};
247+
248+
return (
249+
<div>
250+
<input type="text" value={value} onChange={handleChange} />
251+
<span>{value?.length} characters</span>
252+
</div>
253+
);
254+
}
255+
}
256+
257+
customElements.define('react-text-input', ReactTextInputElement);
258+
----
259+
260+
=== Server-Side Vaadin Component Wrapping the React Component
261+
Next, create a Vaadin component that wraps the React component and extends `AbstractSinglePropertyField`.
262+
263+
[source,java]
264+
----
265+
// Package: com.example.application.ui
266+
267+
import com.vaadin.flow.component.Tag;
268+
import com.vaadin.flow.component.dependency.JsModule;
269+
import com.vaadin.flow.component.AbstractSinglePropertyField;
270+
271+
@Tag("react-text-input")
272+
@JsModule("./react-text-input.tsx")
273+
public class ReactTextField extends AbstractSinglePropertyField<ReactTextField, String> {
274+
public ReactTextField() {
275+
super("value", "", false);
276+
}
277+
}
278+
----
279+
280+
=== Using the React Component in a Vaadin Form
281+
Now, you can use `ReactTextField` like any other Vaadin component within a form:
282+
283+
[source,java]
284+
----
285+
Binder<Person> binder = new Binder<>(Person.class);
286+
ReactTextField reactTextField = new ReactTextField();
287+
288+
binder.forField(reactTextField).bind(Person::getName, Person::setName);
289+
290+
add(reactTextField);
291+
----

0 commit comments

Comments
 (0)