|
| 1 | + |
| 2 | +When wrapping a React component, you may need to define custom code or hooks that are specific to the component. This is done by defining the `add_custom_code`or `add_hooks` methods in your component class. |
| 3 | + |
| 4 | +## Custom Code |
| 5 | + |
| 6 | +Custom code is any JS code that need to be included in your page, but not necessarily in the component itself. This can include things like CSS styles, JS libraries, or any other code that needs to be included in the page. |
| 7 | + |
| 8 | +```python |
| 9 | +class CustomCodeComponent(MyBaseComponent): |
| 10 | + """MyComponent.""" |
| 11 | + |
| 12 | + def add_custom_code(self) -> list[str]: |
| 13 | + """Add custom code to the component.""" |
| 14 | + code1 = """const customVariable = "Custom code1";""" |
| 15 | + code2 = """console.log(customVariable);""" |
| 16 | + |
| 17 | + return [code1, code2] |
| 18 | +``` |
| 19 | + |
| 20 | +The above example will render the following JS code in the page: |
| 21 | + |
| 22 | +```javascript |
| 23 | +/* import here */ |
| 24 | + |
| 25 | +const customVariable = "Custom code1"; |
| 26 | +console.log(customVariable); |
| 27 | + |
| 28 | +/* rest of the page code */ |
| 29 | +``` |
| 30 | + |
| 31 | +## Custom Hooks |
| 32 | +Custom hooks are any hooks that need to be included in your component. This can include things like `useEffect`, `useState`, or any other hooks from the library you are wrapping. |
| 33 | + |
| 34 | +- Simple hooks can be added as strings. |
| 35 | +- More complex hooks that need to have special import or be written in a specific order can be added as `rx.Var` with a `VarData` object to specify the position of the hook. |
| 36 | + - The `imports` attribute of the `VarData` object can be used to specify any imports that need to be included in the component. |
| 37 | + - The `position` attribute of the `VarData` object can be set to `Hooks.HookPosition.PRE_TRIGGER` or `Hooks.HookPosition.POST_TRIGGER` to specify the position of the hook in the component. |
| 38 | + |
| 39 | +```md alert info |
| 40 | +# The `position` attribute is only used for hooks that need to be written in a specific order. |
| 41 | +- If an event handler need to refer to a variable defined in a hook, the hook should be written before the event handler. |
| 42 | +- If a hook need to refer to the memoized event handler by name, the hook should be written after the event handler. |
| 43 | +``` |
| 44 | + |
| 45 | +```python |
| 46 | +from reflex.vars.base import Var, VarData |
| 47 | +from reflex.constants import Hooks |
| 48 | +from reflex.components.el.elements import Div |
| 49 | + |
| 50 | +class ComponentWithHooks(Div, MyBaseComponent): |
| 51 | + """MyComponent.""" |
| 52 | + |
| 53 | + def add_hooks(self) -> list[str| Var]: |
| 54 | + """Add hooks to the component.""" |
| 55 | + hooks = [] |
| 56 | + hooks1 = """const customHookVariable = "some value";""" |
| 57 | + hooks.append(hooks1) |
| 58 | + |
| 59 | + # A hook that need to be written before the memoized event handlers. |
| 60 | + hooks2 = Var( |
| 61 | + """useEffect(() => { |
| 62 | + console.log("PreTrigger: " + customHookVariable); |
| 63 | + }, []); |
| 64 | + """, |
| 65 | + _var_data=VarData( |
| 66 | + imports=\{"react": ["useEffect"],\}, |
| 67 | + position=Hooks.HookPosition.PRE_TRIGGER |
| 68 | + ), |
| 69 | + ) |
| 70 | + hooks.append(hooks2) |
| 71 | + |
| 72 | + hooks3 = Var( |
| 73 | + """useEffect(() => { |
| 74 | + console.log("PostTrigger: " + customHookVariable); |
| 75 | + }, []); |
| 76 | + """, |
| 77 | + _var_data=VarData( |
| 78 | + imports=\{"react": ["useEffect"],\}, |
| 79 | + position=Hooks.HookPosition.POST_TRIGGER |
| 80 | + ), |
| 81 | + ) |
| 82 | + hooks.append(hooks3) |
| 83 | + return hooks |
| 84 | +``` |
| 85 | + |
| 86 | +The `ComponentWithHooks` will be rendered in the component in the following way: |
| 87 | + |
| 88 | +```javascript |
| 89 | +export function Div_7178f430b7b371af8a12d8265d65ab9b() { |
| 90 | + const customHookVariable = "some value"; |
| 91 | + |
| 92 | + useEffect(() => { |
| 93 | + console.log("PreTrigger: " + customHookVariable); |
| 94 | + }, []); |
| 95 | + |
| 96 | + /* memoized triggers such as on_click, on_change, etc will render here */ |
| 97 | + |
| 98 | + useEffect(() => { |
| 99 | + console.log("PostTrigger: "+ customHookVariable); |
| 100 | + }, []); |
| 101 | + |
| 102 | + return jsx("div", \{\}); |
| 103 | +} |
| 104 | +``` |
| 105 | + |
| 106 | +```md alert info |
| 107 | +# You can mix custom code and hooks in the same component. Hooks can access a variable defined in the custom code, but custom code cannot access a variable defined in a hook. |
| 108 | +``` |
0 commit comments