Skip to content

Conditional Rendering & Updating

What are they?

React Signify gives you two powerful tools to control when your state updates and when your components re-render:

  • conditionUpdating: Decides when to accept new values
  • conditionRendering: Decides when to re-render components

Think of them as "gatekeepers" that prevent unnecessary work and improve performance.

tsx
// Only update when condition is met
signify.conditionUpdating((prevValue, newValue) => boolean);

// Only re-render when condition is met
signify.conditionRendering((currentValue) => boolean);

How the Flow Works

Here's what happens when you call .set():

1. Call .set(newValue)
2. → Check conditionUpdating(oldValue, newValue)
3. → If true: Update the value
4. → Check conditionRendering(currentValue)
5. → If true: Re-render components

Key insight: Both conditions must return true for a complete update + re-render cycle.

conditionUpdating - Control When Values Change

What it does

Controls whether a new value should be accepted into your state.

tsx
const sCounter = signify(0);

// Only allow positive numbers
sCounter.conditionUpdating((oldValue, newValue) => newValue >= 0);

sCounter.set(5); // ✅ Works: 0 → 5
sCounter.set(-1); // ❌ Blocked, stays 5
sCounter.set(10); // ✅ Works: 5 → 10

Common Use Cases

1. Validation

tsx
const sUserAge = signify(0);
sUserAge.conditionUpdating((prev, curr) => curr >= 18 && curr <= 120);

2. Only Allow Increases

tsx
const sScore = signify(0);
sScore.conditionUpdating((prev, curr) => curr >= prev);

3. Limit Array Size

tsx
const items = signify<string[]>([]);
items.conditionUpdating((prev, curr) => curr.length <= 100);

4. Prevent Too Frequent Updates

tsx
let lastUpdate = 0;
const sData = signify("");
sData.conditionUpdating(() => {
  const now = Date.now();
  const canUpdate = now - lastUpdate > 500; // 500ms gap
  if (canUpdate) lastUpdate = now;
  return canUpdate;
});

conditionRendering - Control When Components Re-render

What it does

Controls whether components should re-render when the state changes.

tsx
const sCounter = signify(0);

// Only re-render on even numbers
sCounter.conditionRendering((value) => value % 2 === 0);

function Counter() {
  const count = sCounter.use();
  return <div>Count: {count}</div>;
}

sCounter.set(1); // ❌ No re-render (1 is odd)
sCounter.set(2); // ✅ Re-renders (2 is even)
sCounter.set(3); // ❌ No re-render (3 is odd)

Common Use Cases

1. Skip Loading States

tsx
const status = signify<"loading" | "success" | "error">("loading");
status.conditionRendering((value) => value !== "loading");

2. Only Show Important Notifications

tsx
const notifications = signify<Array<{ type: string }>>([]);
notifications.conditionRendering((items) =>
  items.some((item) => item.type === "urgent")
);

3. Performance - Skip Empty States

tsx
const searchResults = signify<string[]>([]);
searchResults.conditionRendering((results) => results.length > 0);

4. Time-based Rendering

tsx
const sLivePrice = signify(100);
sLivePrice.conditionRendering(() => {
  const hour = new Date().getHours();
  return hour >= 9 && hour <= 17; // Only during business hours
});

Using Both Together

You can combine both conditions for maximum control:

tsx
const sUserProfile = signify({ name: "", email: "", isValid: false });

// Control updates: Only accept valid data
sUserProfile.conditionUpdating((prev, curr) => {
  return curr.email.includes("@") && curr.name.length > 0;
});

// Control rendering: Only show when profile is complete
sUserProfile.conditionRendering((profile) => {
  return profile.isValid;
});

function ProfileComponent() {
  const profile = sUserProfile.use();
  return <div>Welcome, {profile.name}!</div>;
}

// This will update but not render (email invalid)
sUserProfile.set({ name: "John", email: "invalid", isValid: true }); // ❌ Blocked by conditionUpdating

// This will update and render
sUserProfile.set({ name: "John", email: "john@email.com", isValid: true }); // ✅ Both conditions pass

Real-world Example: Shopping Cart

tsx
const sCart = signify({ items: [], total: 0 });

// Only accept valid cart updates
sCart.conditionUpdating((prev, curr) => {
  const calculatedTotal = curr.items.reduce((sum, item) => sum + item.price, 0);
  return Math.abs(calculatedTotal - curr.total) < 0.01; // Total must match
});

// Only render when cart has items
sCart.conditionRendering((cart) => cart.items.length > 0);

function Cart() {
  const { items, total } = sCart.use();
  return (
    <div>
      Cart: {items.length} items, ${total}
    </div>
  );
}

Quick Reference

Common Patterns

Form Validation

tsx
const sForm = signify({ email: "", password: "" });
sForm.conditionUpdating(
  (prev, curr) => curr.email.includes("@") && curr.password.length >= 8
);

Real-time Data (rate limiting)

tsx
const sLiveData = signify(0);
sLiveData.conditionUpdating(
  (prev, curr) => Math.abs(curr - prev) > 0.01 // Only update if change > 1%
);

Skip Loading States

tsx
const status = signify<"loading" | "ready">("loading");
status.conditionRendering((value) => value === "ready");

Game Score (no decreases)

tsx
const score = signify(0);
score.conditionUpdating((prev, curr) => curr >= prev);

Best Practices

✅ Do

  • Keep condition functions simple and fast
  • Use for validation and performance optimization
  • Document why you're using each condition

❌ Don't

  • Use expensive operations in conditions
  • Make async calls in condition functions
  • Over-engineer simple use cases
tsx
// ✅ Good: Simple and fast
counter.conditionUpdating((prev, curr) => curr >= 0);

// ❌ Avoid: Complex and slow
data.conditionUpdating((prev, curr) => {
  return expensiveCalculation(curr) && networkCall(curr); // Too complex!
});

When to Use

Use conditionUpdating when:

  • Validating input data
  • Preventing invalid state changes
  • Rate limiting updates

Use conditionRendering when:

  • Skipping unnecessary re-renders
  • Hiding components during loading
  • Performance optimization

Use both when:

  • You need full control over both state and UI updates
  • Building complex forms or real-time applications

💡 Remember: These are optimization tools. Start simple, then add conditions when you need them!

Released under the MIT License.