AlgoInsight

Q&A

How to customize a button in NativeBase

By AlgoInsight Team2026-06-07

Overview

NativeBase is a React Native (and web) UI library with a themeable component system. Its Button is highly configurable: most visual tweaks are just props, interaction states use the _-prefixed style props (_pressed, _hover), and global customization lives in the theme. This mirrors utility-first styling but in a component/props form.

graph TD
    A[Customize NativeBase Button] --> B[Per-instance props: variant, colorScheme, size]
    A --> C[Style props: bg, borderRadius, px, _text]
    A --> D[State props: _pressed, _hover, _disabled]
    A --> E[App-wide: extendTheme → components.Button]
    style E fill:#1e1b4b,color:#fff

Built-in Props

import { Button } from "native-base";

<Button variant="solid"   colorScheme="primary">Solid</Button>
<Button variant="outline" colorScheme="secondary">Outline</Button>
<Button variant="ghost">Ghost</Button>
<Button variant="link">Link</Button>

<Button size="sm">Small</Button>
<Button size="lg">Large</Button>

Inline Style Props

NativeBase exposes style props directly on the component:

<Button
  bg="indigo.600"          // background color
  borderRadius="full"      // pill shape
  px={6} py={3}            // horizontal/vertical padding
  _text={{ fontSize: "md", fontWeight: "bold", color: "white" }}  // label styling
>
  Custom
</Button>

The _text prop styles the inner text; this nested-style pattern is how you reach child elements.

Styling Interaction States

The _-prefixed props target states:

<Button
  bg="indigo.600"
  _pressed={{ bg: "indigo.800" }}     // while pressed
  _hover={{ bg: "indigo.700" }}        // on web hover
  _disabled={{ opacity: 0.4 }}         // when disabled
>
  Stateful
</Button>

Icons and Loading State

import { Button, Icon } from "native-base";
import { MaterialIcons } from "@expo/vector-icons";

<Button leftIcon={<Icon as={MaterialIcons} name="save" size="sm" />}>
  Save
</Button>

<Button isLoading isLoadingText="Submitting">Submit</Button>

isLoading automatically shows a spinner and disables the button - no manual state plumbing for the visual.

App-Wide Customization via Theme

For consistent buttons across the app, override the Button component in a custom theme with extendTheme:

import { extendTheme, NativeBaseProvider } from "native-base";

const theme = extendTheme({
  components: {
    Button: {
      baseStyle: { borderRadius: "lg" },
      defaultProps: { colorScheme: "indigo", size: "md" },
      variants: {
        brand: () => ({ bg: "indigo.600", _text: { color: "white" } }),
      },
    },
  },
  colors: {
    indigo: { 600: "#6366f1", 700: "#4f46e5", 800: "#4338ca" },
  },
});

// wrap the app:
<NativeBaseProvider theme={theme}>{/* ... */}</NativeBaseProvider>
// then anywhere:
<Button variant="brand">Branded</Button>

baseStyle applies to all buttons, defaultProps sets defaults, and custom variants create reusable named styles.

Why This Matters in Interviews

React Native / NativeBase questions check whether you customize via the theming system rather than scattering inline styles. The progression to demonstrate: per-instance props (variant, colorScheme, size) → style props (bg, _text) → state props (_pressed) → app-wide extendTheme overrides with custom variants. Knowing _text for the label and _pressed/_hover for states, plus built-in isLoading, shows real familiarity.

Common Pitfalls

References

More answers