react_core 0.1.0
react_core: ^0.1.0 copied to clipboard
Platform-agnostic React component, node, and hook primitives for Dart.
react_core #
Portable React node, component, hook, context, ref, and runtime contracts for Dart.
react_core contains no dart:js_interop or server-framework dependency. The same
component model can therefore be consumed by browser rendering, Node SSR,
native tests, code generation, and tooling.
Installation #
dependencies:
react_core: ^0.1.0
Web applications normally depend on react_dom instead. Its entrypoint
re-exports this package together with the typed host-element API.
Components #
Author components as functions with one named record parameter:
import 'package:react_dom/react_dom.dart';
@reactComponent
ReactNode UserCard(({
required String name,
String? role,
ReactChildren children,
}) props) {
final (expanded, setExpanded) = useState(false);
return article(
className: classNames('user-card', {'expanded': expanded}),
children: [
h2(key: 'name', children: [props.name]),
if (props.role case final role?) p(key: 'role', children: [role]),
button(
key: 'toggle',
type: 'button',
onClick: (_) => setExpanded(!expanded),
children: [expanded ? 'Collapse' : 'Expand'],
),
...props.children,
],
);
}
Run react generate, react build, or react serve. The generated callable
factory is synchronized to
package:my_app/.generated/user_card.react.dart and is imported by callers,
not by the authored component itself.
Component factories accept a stable key, normalize ReactChildren, and
provide a .props() builder for composition-heavy call sites.
The portable package also exposes small composition helpers:
return section(children: [
when(isSignedIn, AccountSummary()),
unless(isSignedIn, LoginPrompt()),
...each(rows, (row, index) => RowView(row: row, index: index)),
]);
joinClassNames is available in the renderer-neutral package for libraries
that need conditional class composition without depending on the Web package.
The Web entrypoint additionally provides classNames and the typed css
style-map helper.
For generated or registered components, ReactComponentFactory<P> provides a
typed portable invocation when a component ID is more convenient than a
generated named-parameter wrapper:
final Greeting = component<GreetingProps>(
const ComponentId('package:example/greeting.dart#Greeting'),
metadata: const ReactComponentMetadata(name: 'Greeting'),
);
final node = Greeting(const GreetingProps(name: 'Ada'));
The factory creates the same Component<P> node consumed by browser, SSR, and
test renderers. It does not register a component by itself; registration is
still owned by react_codegen and react_tool.
Node model #
Every render result is a ReactNode. The portable hierarchy includes:
| Type | Purpose |
|---|---|
Component<P> |
Invocation of a generated Dart component with typed record props. |
HostNode<P> |
Portable host element emitted by typed react_web factories. |
ForeignComponent |
Registered JavaScript or TypeScript React component. |
Text |
Explicit text node. Strings and numbers are also normalized as children. |
Fragment |
Keyable child group without a host wrapper. |
Empty |
Deliberately absent output. |
LazyNode, MemoizedNode, ForwardRefNode |
React lazy, memo, and ref-forwarding contracts. |
Application code should use the typed factories re-exported by react_dom
rather than constructing HostNode records manually.
Children and props helpers #
ReactChildren is Iterable<Object?>. normalizeChildren converts nested
iterables, strings, numbers, booleans, nulls, and existing nodes into the
portable tree.
Web-facing helpers available through react_dom include:
css(...)for typed style maps;classNames(...)for conditional class composition;dataAttributes(...)andaria(...)for additional props;- generated
<Element>.props()builders for large prop sets.
Hooks #
The public hook surface delegates to the active ReactBinding:
useState,useReducer,useEffect, anduseLayoutEffect;useMemo,useCallback,useRef, anduseImperativeHandle;useContext,useSyncExternalStore,useTransition, anduseDeferredValue;- React 18/19 APIs including
useId,useOptimistic, anduseActionState.
The workspace supports React 18 and 19. A hook missing from the active runtime
throws a descriptive UnsupportedError; do not infer API support only from a
successful npm installation.
Hooks must run while a component is rendered and at the top level of a
component or custom use* function. react_analysis and react_analyzer
provide matching diagnostics.
Runtime features #
The package also defines portable contracts for contexts, providers, refs,
error boundaries, suspense, strict mode, portals, memoization, lazy components,
and runtime capability checks. Renderers implement those contracts in
react_js, react_server, and react_testing.
Package boundaries #
react_dom: recommended web component entrypoint and mount/hydrate APIs;react_web: generated DOM/Web surface and SSR-compatible host shapes;react_js: JavaScript renderer and hook binding;react_server: transport-neutral SSR and server-function primitives;react_codegen: component and server-function generation;react_testing: native component/runtime harnesses.