Skip to content

Commit

Permalink
feat: stateless useFiber, backport React support (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
CodyJasonBennett authored Apr 9, 2024
1 parent b6f6a2b commit d363fcc
Show file tree
Hide file tree
Showing 10 changed files with 1,258 additions and 1,044 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,6 @@ jobs:

- name: Run tests
run: yarn test --silent

- name: Check for regressions
run: yarn lint
81 changes: 22 additions & 59 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,52 +12,21 @@
</a>
</p>

A collection of escape hatches exploring `React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED`.
A collection of escape hatches for React.

As such, you can go beyond React's component abstraction; components are self-aware and can tap into the React Fiber tree. This enables powerful abstractions like stateless queries and sharing React Context across concurrent renderers. I'm sure you want me to tell you how safe and stable this all is.
As such, you can go beyond React's component abstraction; components are self-aware and can tap into the [React Fiber](https://youtu.be/ZCuYPiUIONs) tree. This enables powerful abstractions that can modify or extend React behavior without explicitly taking reconciliation into your own hands.

## Table of Contents

- [Components](#components)
- [FiberProvider](#fiberprovider)
- [Hooks](#hooks)
- [useFiber](#useFiber)
- [useContainer](#useContainer)
- [useNearestChild](#useNearestChild)
- [useNearestParent](#useNearestParent)
- [useContextMap](#useContextMap)
- [useContextBridge](#useContextBridge)
- [Utils](#utils)
- [traverseFiber](#traverseFiber)
- [useFiber](#useFiber)
- [useContainer](#useContainer)
- [useNearestChild](#useNearestChild)
- [useNearestParent](#useNearestParent)
- [useContextMap](#useContextMap)
- [useContextBridge](#useContextBridge)
- [traverseFiber](#traverseFiber)

## Components

### FiberProvider

A react-internal `Fiber` provider. This component binds React children to the React Fiber tree. Call its-fine hooks within this.

> **Note**: pmndrs renderers like react-three-fiber implement this internally to make use of [`useContextBridge`](#usecontextbridge), so you would only need this when using hooks inside of `react-dom` or `react-native`.
```tsx
import * as ReactDOM from 'react-dom/client'
import { FiberProvider, useFiber } from 'its-fine'

function App() {
const fiber = useFiber()
}

ReactDOM.createRoot(document.getElementById('root')!).render(
<FiberProvider>
<App />
</FiberProvider>,
)
```

## Hooks

Useful React hook abstractions for manipulating and querying from a component. These must be called within a [`FiberProvider`](#fiberprovider) component.

### useFiber
## useFiber

Returns the current react-internal `Fiber`. This is an implementation detail of [react-reconciler](https://github.com/facebook/react/tree/main/packages/react-reconciler).

Expand All @@ -74,7 +43,7 @@ function Component() {
}
```

### useContainer
## useContainer

Returns the current react-reconciler container info passed to `Reconciler.createContainer`.

Expand All @@ -93,7 +62,7 @@ function Component() {
}
```

### useNearestChild
## useNearestChild

Returns the nearest react-reconciler child instance or the node created from `Reconciler.createInstance`.

Expand All @@ -120,7 +89,7 @@ function Component() {
}
```

### useNearestParent
## useNearestParent

Returns the nearest react-reconciler parent instance or the node created from `Reconciler.createInstance`.

Expand Down Expand Up @@ -149,7 +118,7 @@ function Component() {
</div>
```

### useContextMap
## useContextMap

Returns a map of all contexts and their values.

Expand All @@ -165,7 +134,7 @@ function Component() {
}
```

### useContextBridge
## useContextBridge

React Context currently cannot be shared across [React renderers](https://reactjs.org/docs/codebase-overview.html#renderers) but explicitly forwarded between providers (see [react#17275](https://github.com/facebook/react/issues/17275)). This hook returns a `ContextBridge` of live context providers to pierce Context across renderers.

Expand All @@ -179,7 +148,7 @@ import * as ReactNil from 'react-nil'
// react-dom is a primary renderer that works on top of a secondary renderer.
// This also includes react-native, react-pixi, etc.
import * as ReactDOM from 'react-dom/client'
import { type ContextBridge, useContextBridge, FiberProvider } from 'its-fine'
import { type ContextBridge, useContextBridge } from 'its-fine'

function Canvas(props: { children: React.ReactNode }) {
// Returns a bridged context provider that forwards context
Expand All @@ -200,21 +169,15 @@ function Component() {
// Renders into a primary renderer like react-dom or react-native,
// DOMContext wraps Canvas and is bridged into Component
ReactDOM.createRoot(document.getElementById('root')!).render(
<FiberProvider>
<DOMContext.Provider value="Hello from react-dom">
<Canvas>
<Component />
</Canvas>
</DOMContext.Provider>
</FiberProvider>,
<DOMContext.Provider value="Hello from react-dom">
<Canvas>
<Component />
</Canvas>
</DOMContext.Provider>
)
```

## Utils

Additional exported utility functions for raw handling of Fibers.

### traverseFiber
## traverseFiber

Traverses up or down a `Fiber`, return `true` to stop and select a node.

Expand Down
23 changes: 10 additions & 13 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,25 +28,22 @@
"sideEffects": false,
"devDependencies": {
"@types/node": "^18.7.15",
"@types/react": "^18.0.17",
"@types/react-test-renderer": "^18.0.0",
"react": "^18.2.0",
"react-nil": "^1.2.0",
"react-test-renderer": "^18.2.0",
"rimraf": "^3.0.2",
"suspend-react": "^0.0.8",
"typescript": "^4.7.4",
"vite": "^3.1.0",
"vitest": "^0.23.1"
"react-reconciler": "^0.29.0",
"typescript": "^5.4.4",
"vite": "^5.2.8",
"vitest": "^1.4.0"
},
"dependencies": {
"@types/react-reconciler": "^0.28.0"
"@types/react": "*",
"@types/react-reconciler": "*"
},
"peerDependencies": {
"react": ">=18.0"
"react": ">=16.8"
},
"scripts": {
"build": "rimraf dist && vite build && tsc",
"test": "vitest run"
"build": "vite build",
"test": "vitest run --reporter verbose",
"lint": "tsc"
}
}
Loading

0 comments on commit d363fcc

Please sign in to comment.