
Company News
Meet the Socket Team at RSAC and BSidesSF 2026
Join Socket for live demos, rooftop happy hours, and one-on-one meetings during BSidesSF and RSA 2026 in San Francisco.
@blac/react
Advanced tools
A powerful React integration for the Blac state management library, providing seamless integration between React components and Blac's reactive state management system.
A powerful React integration for the Blac state management library, providing seamless integration between React components and Blac's reactive state management system.
All methods in Bloc or Cubit classes must use arrow function syntax (method = () => {}) instead of the traditional method syntax (method() {}). This is because arrow functions automatically bind this to the class instance. Without this binding, methods called from React components would lose their context and could not access instance properties like this.state or this.emit().
// Correct way to define methods in your Bloc/Cubit classes
class CounterBloc extends Cubit<CounterState> {
increment = () => {
this.emit({ ...this.state, count: this.state.count + 1 });
}
decrement = () => {
this.emit({ ...this.state, count: this.state.count - 1 });
}
}
// Incorrect way (will cause issues when called from React):
class CounterBloc extends Cubit<CounterState> {
increment() { // ❌ Will lose 'this' context when called from components
this.emit({ ...this.state, count: this.state.count + 1 });
}
}
npm install @blac/react
# or
yarn add @blac/react
# or
pnpm add @blac/react
import { useBloc } from '@blac/react';
import { CounterBloc } from './CounterBloc';
function Counter() {
const [state, counterBloc] = useBloc(CounterBloc);
return (
<div>
<p>Count: {state.count}</p>
<button onClick={() => counterBloc.increment()}>Increment</button>
</div>
);
}
The useBloc hook provides a simple way to connect your React components to Blac's state management system:
const [state, bloc] = useBloc(YourBloc);
The hook accepts configuration options for more control:
const [state, bloc] = useBloc(YourBloc, {
id: 'custom-id', // Optional: Custom identifier for the bloc
props: { /* ... */ }, // Optional: Props to pass to the bloc
onMount: (bloc) => { /* ... */ }, // Optional: Callback when bloc is mounted (similar to useEffect(<>, []))
selector: (currentState, previousState, instance) => [/* ... */], // Optional: Custom dependency tracking
});
The hook automatically tracks which state properties and bloc instance properties are accessed in your component and only triggers re-renders when those specific values change:
function UserProfile() {
const [state, userBloc] = useBloc(UserBloc);
// Only re-renders when state.name changes
return <h1>{state.name}</h1>;
}
This also works for getters and computed properties on the Bloc or Cubit class:
function UserProfile() {
const [state, userBloc] = useBloc(UserBloc);
// Only re-renders when:
// - state.firstName changes, OR
// - state.lastName changes (because the getter accesses these properties)
return <h1>{userBloc.fullName}</h1>; // Assuming fullName is a getter
}
The dependency tracking system uses JavaScript Proxies to monitor property access during component renders:
state.propertyName, it's automatically trackedbloc.computedValue, it's automatically trackedFor more control over when your component re-renders, you can provide a custom dependency selector. The selector function receives the current state, previous state, and bloc instance, and should return an array of values to track:
const [state, bloc] = useBloc(YourBloc, {
selector: (currentState, previousState, instance) => [
currentState.specificField,
currentState.anotherField,
instance.computedValue // You can also track computed properties from the bloc instance
]
});
The component will only re-render when any of the values in the returned array change (using Object.is comparison, similar to React's useEffect dependency array).
Track only specific state properties:
const [state, userBloc] = useBloc(UserBloc, {
selector: (currentState) => [
currentState.name,
currentState.email
] // Only re-render when name or email changes, ignore other properties
});
Track computed values:
const [state, shoppingCartBloc] = useBloc(ShoppingCartBloc, {
selector: (currentState, previousState, instance) => [
instance.totalPrice, // Computed getter
currentState.items.length // Number of items
] // Only re-render when total price or item count changes
});
Compare with previous state:
const [state, chatBloc] = useBloc(ChatBloc, {
selector: (currentState, previousState) => [
currentState.messages.length > (previousState?.messages.length || 0) ? 'new-message' : 'no-change'
] // Only re-render when new messages are added, not when existing messages change
});
function useBloc<B extends BlocConstructor<BlocGeneric>>(
bloc: B,
options?: BlocHookOptions<InstanceType<B>>
): [BlocState<InstanceType<B>>, InstanceType<B>]
id?: string - Custom identifier for the bloc instanceprops?: InferPropsFromGeneric<B> - Props to pass to the bloconMount?: (bloc: B) => void - Callback function invoked when the react component (the consumer) is connected to the bloc instanceselector?: (currentState: BlocState<InstanceType<B>>, previousState: BlocState<InstanceType<B>> | undefined, instance: InstanceType<B>) => unknown[] - Function to select dependencies for re-rendersUse Isolated Blocs: When you need component-specific state, use isolated blocs:
class MyIsolatedBloc extends BlocBase {
static isolated = true;
// ... rest of your bloc implementation
}
Use Custom Identifiers: When you need multiple independent instances of the same Bloc type, use custom identifiers to manage different state contexts:
// In a chat application with multiple chat rooms
function ChatRoom({ roomId }: { roomId: string }) {
const [state, chatBloc] = useBloc(ChatBloc, {
id: `chat-${roomId}`, // Each room gets its own instance
props: { roomId }
});
return (
<div>
<h2>Room: {roomId}</h2>
{state.messages.map(msg => (
<Message key={msg.id} message={msg} />
))}
</div>
);
}
// Usage:
function ChatApp() {
return (
<div>
<ChatRoom roomId="general" />
<ChatRoom roomId="support" />
</div>
);
}
Choose the Right Dependency Strategy:
Type Safety: Take advantage of TypeScript's type inference for better development experience and catch errors early.
Contributions are welcome! Please feel free to submit a Pull Request.
MIT
FAQs
> ⚠️ **Warning:** This project is currently under active development. The API may change in future releases. Use with caution in production environments.
The npm package @blac/react receives a total of 5 weekly downloads. As such, @blac/react popularity was classified as not popular.
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.

Company News
Join Socket for live demos, rooftop happy hours, and one-on-one meetings during BSidesSF and RSA 2026 in San Francisco.

Research
/Security News
Malicious Packagist packages disguised as Laravel utilities install an encrypted PHP RAT via Composer dependencies, enabling remote access and C2 callbacks.

Research
/Security News
OpenVSX releases of Aqua Trivy 1.8.12 and 1.8.13 contained injected natural-language prompts that abuse local AI coding agents for system inspection and potential data exfiltration.