Skip to content

Wrap ProposalCard and ApprovalBar with React.memo and memoize expensive derived values to prevent unnecessary re-renders on proposal list refreshes #186

Description

@thegreatfeez

Frontend — Code Quality

Summary

Every time the contract polling cycle completes, the entire proposal list re-renders even when individual proposal data has not changed. This issue reduces wasted renders by memoizing the two most frequently rendered components and the derived proposal arrays that feed them.

Background

ProposalCard.tsx and ApprovalBar.tsx are plain function components with no memoization. In App.tsx, the activeProposals and historyProposals arrays are derived inline from the proposals state on every render, creating new array references each time even when the underlying data is identical. The onApprove and onExecute callbacks passed to ProposalCard are also recreated each render because they are defined as arrow functions inline in App.tsx.

What Needs to Be Done

  1. In frontend/src/components/ProposalCard.tsx, wrap the component export with React.memo so it only re-renders when its own props change.
  2. In frontend/src/components/ApprovalBar.tsx, wrap the component export with React.memo for the same reason.
  3. In frontend/src/App.tsx, replace the inline activeProposals and historyProposals array derivations with useMemo calls that depend only on the proposals array, so the derived arrays keep a stable reference between renders when proposals have not changed.
  4. In frontend/src/App.tsx, wrap the handleApprove and handleExecute callback functions with useCallback so their references stay stable between renders and do not defeat the memoization added in steps 1 and 2.

Acceptance Criteria

  • ProposalCard is wrapped with React.memo.
  • ApprovalBar is wrapped with React.memo.
  • activeProposals and historyProposals in App.tsx are derived with useMemo.
  • handleApprove and handleExecute in App.tsx are wrapped with useCallback.
  • The app compiles and behaves identically to before with no visual regressions.

Files to Look At

  • frontend/src/components/ProposalCard.tsx — wrap with React.memo
  • frontend/src/components/ApprovalBar.tsx — wrap with React.memo
  • frontend/src/App.tsx — add useMemo for derived arrays and useCallback for handlers

Difficulty: Medium

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions