Skip to content

useBox Guide

useBox is a custom React hook from F-Box that allows developers to manage static or immutable state efficiently. By encapsulating values within Box objects, useBox facilitates functional programming paradigms to streamline state transformations and ensure immutability.


Why Choose useBox?

useBox is optimized for managing static values or derived states that remain constant or infrequently change. It integrates the F-Box Box abstraction into React components, offering a declarative, immutable, and composable approach to state management.


Key Benefits of useBox

  1. Simplified State Management: Encapsulate static values into Box objects for easy handling and transformations.
  2. Immutability: Ensure values remain unchanged, avoiding side effects and promoting predictable behavior.
  3. Functional Composability: Leverage functional operators like <$> and <*> for clean and reusable state derivations.
  4. Seamless Integration: Incorporate Box values directly into React components, maintaining React’s declarative nature.

Practical Use Cases

1. Managing Global Configuration

Static application-wide configurations are ideal candidates for useBox. This approach ensures consistency and immutability for values like app metadata.

Code Example

config.ts
import { Box } from "f-box-core"
export const configBox = Box.pack({
appName: "YourAwesomeApp",
appVersion: "1.0.0",
})
AppHeader.ts
import { useBox } from "f-box-react"
import { configBox } from "./config"
function AppHeader() {
const [{ appName, appVersion }] = useBox(configBox)
return (
<header>
<h1>{appName}</h1>
<small>Version: {appVersion}</small>
</header>
)
}
export default AppHeader

Explanation

  • configBox wraps static configuration values like appName and appVersion.
  • These values are accessed using useBox, ensuring immutability and ease of reuse across components.
  • This pattern is particularly useful for global settings that remain consistent throughout the application.

2. Creating Derived Values with map

Derived values can be generated by applying functional transformations to Box values. This is achieved using the map operator <$>.

Code Example

DerivedExample.tsx
import { useBox } from "f-box-react"
function DerivedExample() {
const [base, baseBox] = useBox(5)
const [squared] = useBox(() => baseBox["<$>"]((x) => x ** 2))
const [cubed] = useBox(() => baseBox["<$>"]((x) => x ** 3))
return (
<div>
<p>Base Value: {base}</p>
<p>Squared: {squared}</p>
<p>Cubed: {cubed}</p>
</div>
)
}
export default DerivedExample

Explanation

  • The base value 5 is encapsulated in a Box.
  • Derived values, such as the square and cube of the base, are computed using the <$> operator.
  • This approach enables declarative transformations, ensuring immutability and code clarity.

3. Combining Multiple Boxes with <*>

<*> allows you to combine multiple Box values and perform transformations on their contents.

Code Example

CombineBoxes.tsx
import { Box } from "f-box-core"
import { useBox } from "f-box-react"
function CombineBoxes() {
const [x, xBox] = useBox(5)
const [y, yBox] = useBox(10)
const [sum] = useBox(() =>
Box.pack((a: number) => (b: number) => a + b)
["<*>"](xBox)
["<*>"](yBox)
)
return (
<div>
<p>X: {x}</p>
<p>Y: {y}</p>
<p>Sum: {sum}</p>
</div>
)
}
export default CombineBoxes

Explanation

  • sumBox defines a curried function (b) => (a) => a + b and wraps it in a Box.
  • Using <*>, xBox and yBox are combined to compute their sum.
  • This technique is useful for composing multiple static values into a derived result.

4. Sharing State Across Components

Static state encapsulated in a Box can be shared and accessed across multiple components for consistent behavior. This ensures that all components use the same source of truth for static data.

Code Example

globalRoles.ts
import { Box } from "f-box-core"
export const rolesBox = Box.pack(["Admin", "Editor", "Viewer"])
RoleList.tsx
import { useBox } from "f-box-react"
import { rolesBox } from "./globalRoles"
function RoleList() {
const [roles] = useBox(rolesBox)
return (
<ul>
{roles.map((role) => (
<li key={role}>{role}</li>
))}
</ul>
)
}
export default RoleList
App.tsx
import React from "react"
import RoleList from "./RoleList"
function App() {
return (
<div>
<h2>User Roles</h2>
<RoleList />
</div>
)
}
export default App

Explanation

  • rolesBox stores a list of user roles, making it accessible throughout the application.
  • The RoleList component retrieves the list using useBox and displays it as an unordered list.
  • This pattern allows consistent data sharing across components, reducing duplication and potential errors.

Best Practices

  1. Use for Static State: Focus on static or immutable values. For dynamic values, prefer useRBox.
  2. Leverage Functional Operators: Utilize <$> for transformations and <*> for combining values efficiently.
  3. Avoid Direct Mutations: Never modify Box values directly. Always use operators or re-wrap values with Box.pack.

Common Pitfalls

  1. Using useBox for Reactive State: Avoid managing reactive or frequently changing state with useBox. Use useRBox instead.

  2. Direct Mutations: Do not attempt to modify Box values directly. Use functional operators like <$> for immutability.


Conclusion

useBox is a powerful and declarative solution for managing static state in React applications. By leveraging F-Box’s functional programming features, such as composable operators and strong immutability guarantees, developers can build clean, scalable, and maintainable components. Whether you are managing static configurations or derived values, useBox seamlessly integrates into your React projects to enhance state management.


Next Steps

Explore related guides and references to deepen your understanding of F-Box:

  • useRBox Guide: Dive into reactive and dynamic state management with useRBox.
  • useRBoxForm Guide: Simplify form handling and validation with useRBoxForm.