
Security News
AI Agent Lands PRs in Major OSS Projects, Targets Maintainers via Cold Outreach
An AI agent is merging PRs into major OSS projects and cold-emailing maintainers to drum up more work.
@blac/react
Advanced tools
> ⚠️ **Warning:** This project is currently under active development. The API may change in future releases. Use with caution in production environments.
⚠️ Warning: This project is currently under active development. The API may change in future releases. Use with caution in production environments.
React integration for the BlaC state management library with automatic re-render optimization.
npm install @blac/react @blac/core
# or
pnpm add @blac/react @blac/core
# or
yarn add @blac/react @blac/core
import { Cubit } from '@blac/core';
import { useBloc } from '@blac/react';
class CounterCubit extends Cubit<{ count: number }> {
constructor() {
super({ count: 0 });
}
increment = () => this.emit({ count: this.state.count + 1 });
decrement = () => this.emit({ count: this.state.count - 1 });
}
function Counter() {
const [state, counter] = useBloc(CounterCubit);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={counter.increment}>+</button>
<button onClick={counter.decrement}>-</button>
</div>
);
}
Connects a component to a state container with automatic re-renders on state changes.
const [state, bloc, ref] = useBloc(MyBloc);
Returns: [state, bloc, ref]
state - Current state (reactive)bloc - The bloc instance for calling methodsref - Component reference for isolated instancesAuto-tracking (default): Automatically detects which properties you access and only re-renders when those change.
function UserProfile() {
const [state, user] = useBloc(UserBloc);
// Only re-renders when state.name changes
// (state.email changes won't cause re-render)
return <h1>{state.name}</h1>;
}
Manual dependencies: Explicit dependency array like useEffect.
function Counter() {
const [state] = useBloc(CounterBloc, {
dependencies: (state) => [state.count],
});
return <p>{state.count}</p>;
}
No tracking: Returns full state, re-renders on any change.
function FullState() {
const [state] = useBloc(MyBloc, { autoTrack: false });
return <pre>{JSON.stringify(state)}</pre>;
}
useBloc(MyBloc, {
// Tracking mode
autoTrack: true, // Enable/disable auto-tracking (default: true)
dependencies: (state) => [state.prop], // Manual dependencies
// Instance management
instanceId: 'unique-id', // Custom instance identifier
// Lifecycle callbacks
onMount: (bloc) => console.log('Mounted', bloc),
onUnmount: (bloc) => console.log('Unmounted', bloc),
});
Connects to a state container without subscribing to state changes. Use for calling actions without re-renders, or for stateless containers.
const bloc = useBlocActions(MyBloc);
Use cases:
// Stateless services (analytics, navigation, etc.)
function TrackButton() {
const analytics = useBlocActions(AnalyticsService);
return (
<button onClick={() => analytics.trackClick('button')}>Click me</button>
);
}
// Actions-only (no state subscription)
function IncrementButton() {
const counter = useBlocActions(CounterCubit);
return <button onClick={counter.increment}>+</button>;
}
useBlocActions(MyBloc, {
instanceId: 'unique-id', // Custom instance identifier
onMount: (bloc) => bloc.initialize(),
onUnmount: (bloc) => bloc.cleanup(),
});
By default, all components using the same bloc class share one instance:
function ComponentA() {
const [state] = useBloc(CounterCubit);
// Uses shared instance
}
function ComponentB() {
const [state] = useBloc(CounterCubit);
// Uses same shared instance
}
For component-scoped state, use the @blac({ isolated: true }) decorator:
import { Cubit, blac } from '@blac/core';
@blac({ isolated: true })
class FormCubit extends Cubit<FormState> {
// ...
}
function FormA() {
const [state] = useBloc(FormCubit);
// Gets its own instance
}
function FormB() {
const [state] = useBloc(FormCubit);
// Gets a different instance
}
Share instances across specific components with instanceId:
function EditorA() {
const [state] = useBloc(EditorCubit, { instanceId: 'editor-1' });
}
function EditorB() {
const [state] = useBloc(EditorCubit, { instanceId: 'editor-1' });
// Same instance as EditorA
}
function EditorC() {
const [state] = useBloc(EditorCubit, { instanceId: 'editor-2' });
// Different instance
}
Configure global behavior:
import { configureBlacReact } from '@blac/react';
configureBlacReact({
autoTrack: true, // Enable auto-tracking by default (default: true)
});
function useBloc<T extends StateContainerConstructor>(
BlocClass: T,
options?: UseBlocOptions<T>,
): [ExtractState<T>, InstanceType<T>, ComponentRef];
function useBlocActions<T extends StateContainerConstructor>(
BlocClass: T,
options?: UseBlocActionsOptions<InstanceType<T>>,
): InstanceType<T>;
| Option | Type | Description |
|---|---|---|
autoTrack | boolean | Enable auto-tracking (default: true) |
dependencies | (state) => any[] | Manual dependency selector |
instanceId | string | number | Custom instance identifier |
onMount | (bloc) => void | Called when component mounts |
onUnmount | (bloc) => void | Called when component unmounts |
| Option | Type | Description |
|---|---|---|
instanceId | string | number | Custom instance identifier |
onMount | (bloc) => void | Called when component mounts |
onUnmount | (bloc) => void | Called when component unmounts |
useSyncExternalStoreMIT
FAQs
> ⚠️ **Warning:** This project is currently under active development. The API may change in future releases. Use with caution in production environments.
We found that @blac/react demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
An AI agent is merging PRs into major OSS projects and cold-emailing maintainers to drum up more work.

Research
/Security News
Chrome extension CL Suite by @CLMasters neutralizes 2FA for Facebook and Meta Business accounts while exfiltrating Business Manager contact and analytics data.

Security News
After Matplotlib rejected an AI-written PR, the agent fired back with a blog post, igniting debate over AI contributions and maintainer burden.