> ## Documentation Index
> Fetch the complete documentation index at: https://codegeninc-codegen-bot-sdk-docs-2-0.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# React and JSX

GraphSitter exposes several React and JSX-specific APIs for working with modern React codebases.

Key APIs include:

* [Function.is\_jsx](/api-reference/typescript/TSFunction#is-jsx) - Check if a function contains JSX elements
* [Class.jsx\_elements](/api-reference/typescript/TSClass#jsx-elements) - Get all JSX elements in a class
* [Function.jsx\_elements](/api-reference/typescript/TSFunction#jsx-elements) - Get all JSX elements in a function
* [JSXElement](/api-reference/typescript/JSXElement) - Manipulate JSX elements
* [JSXProp](/api-reference/typescript/JSXProp) - Manipulate JSX props

<Tip>
  See [React Modernization](/tutorials/react-modernization) for tutorials and
  applications of the concepts described here
</Tip>

## Detecting React Components with `is_jsx`

Codegen exposes a `is_jsx` property on both classes and functions, which can be used to check if a symbol is a React component.

```python
# Check if a function is a React component
function = file.get_function("MyComponent")
is_component = function.is_jsx  # True for React components

# Check if a class is a React component
class_def = file.get_class("MyClassComponent")
is_component = class_def.is_jsx  # True for React class components
```

## Working with JSX Elements

Given a React component, you can access its JSX elements using the [jsx\_elements](/api-reference/typescript/TSFunction#jsx-elements) property.

You can manipulate these elements by using the [JSXElement](/api-reference/typescript/JSXElement) and [JSXProp](/api-reference/typescript/JSXProp) APIs.

```python
# Get all JSX elements in a component
for element in component.jsx_elements:
    # Access element name
    if element.name == "Button":
        # Wrap element in a div
        element.wrap("<div className='wrapper'>", "</div>")

    # Get specific prop
    specific_prop = element.get_prop("className")

    # Iterate over all props
    for prop in element.props:
        if prop.name == "className":
            # Set prop value
            prop.set_value('"my-classname"')

    # Modify element
    element.set_name("NewComponent")
    element.add_prop("newProp", "{value}")

    # Get child JSX elements
    child_elements = element.jsx_elements

    # Wrap element in a JSX expression (preserves whitespace)
    element.wrap("<div className='wrapper'>", "</div>")
```

## Common React Operations

<Tip>See [React Modernization](/tutorials/react-modernization) for more</Tip>

### Refactoring Components into Separate Files

Split React components into individual files:

```python
# Find (named) React components
react_components = [
    func for func in codebase.functions
    if func.is_jsx and func.name is not None
]

# Filter out those that are not the default export
non_default_components = [
    comp for comp in react_components
    if not comp.export or not comp.export.is_default_export()
]

# Move these non-default components to new files
for component in react_components:
    if component != default_component:
        # Create new file
        new_file_path = '/'.join(component.filepath.split('/')[:-1]) + f"{component.name}.tsx"
        new_file = codebase.create_file(new_file_path)

        # Move component and update imports
        component.move_to_file(new_file, strategy="add_back_edge")
```

<Note>
  See [Moving Symbols](/building-with-codegen/moving-symbols) for more details
  on moving symbols between files.
</Note>

### Updating Component Names and Props

Replace components throughout the codebase with prop updates:

```python
# Find target component
new_component = codebase.get_symbol("NewComponent")

for function in codebase.functions:
    if function.is_jsx:
        # Update JSX elements
        for element in function.jsx_elements:
            if element.name == "OldComponent":
                # Update name
                element.set_name("NewComponent")

                # Edit props
                needs_clsx = not file.has_import("clsx")
                for prop in element.props:
                    if prop.name == "className":
                        prop.set_value('clsx("new-classname")')
                        needs_clsx = True
                    elif prop.name == "onClick":
                        prop.set_name('handleClick')

                # Add import if needed
                if needs_clsx:
                    file.add_import_from_import_source("import clsx from 'clsx'")

                # Add import if needed
                if not file.has_import("NewComponent"):
                    file.add_import(new_component)
```
