Reference
JavaScript SDK
@cubejs-client/react

@cubejs-client/react

@cubejs-client/react provides React Components for easy Cube.js integration in a React app.

useCubeQuery

useCubeQuery<TData, TQuery>(query: TQuery, options?: UseCubeQueryOptions): UseCubeQueryResult<unknown extends TData ? QueryRecordType<TQuery> : TData>

A React hook for executing Cube.js queries

import React from 'react';
import { Table } from 'antd';
import { useCubeQuery }  from '@cubejs-client/react';
 
export default function App() {
  const { resultSet, isLoading, error, progress } = useCubeQuery({
    measures: ['Orders.count'],
    dimensions: ['Orders.createdAt.month'],
  });
 
  if (isLoading) {
    return <div>{progress?.stage || 'Loading...'}</div>;
  }
 
  if (error) {
    return <div>{error.toString()}</div>;
  }
 
  if (!resultSet) {
    return null;
  }
 
  const dataSource = resultSet.tablePivot();
  const columns = resultSet.tableColumns();
 
  return <Table columns={columns} dataSource={dataSource} />;
}
 

Type parameters:

  • TData

  • TQuery: DeeplyReadonly<Query | Query[]>

UseCubeQueryOptions

NameTypeDescription
castNumerics?booleanIf enabled, all members of the 'number' type will be automatically converted to numerical values on the client side
cubejsApi?CubejsApiA CubejsApi instance to use. Taken from the context if the param is not passed
resetResultSetOnChange?booleanWhen true the resultSet will be reset to null first
skip?booleanQuery execution will be skipped when skip is set to true. You can use this flag to avoid sending incomplete queries.
subscribe?booleanUse continuous fetch behavior. See Real-Time Data Fetch

UseCubeQueryResult

NameType
errorError | null
isLoadingboolean
progressProgressResponse
refetch() => Promise<void>
resultSetResultSet<TData> | null

isQueryPresent

isQueryPresent(query: Query | Query[]): boolean

Checks whether the query is ready

useCubeMeta

useCubeMeta(options?: Omit<CubeFetchOptions, "query">): CubeFetchResult<Meta>

QueryBuilder

 QueryBuilder extends React.Component ‹QueryBuilderProps, QueryBuilderState›: 

<QueryBuilder /> is used to build interactive analytics query builders. It abstracts state management and API calls to Cube.js Backend. It uses render prop technique and doesn’t render anything itself, but calls the render function instead.

Example

Open in CodeSandbox (opens in a new tab)

import React from 'react';
import ReactDOM from 'react-dom';
import { Layout, Divider, Empty, Select } from 'antd';
import { QueryBuilder } from '@cubejs-client/react';
import cubejs from '@cubejs-client/core';
import 'antd/dist/antd.css';
 
import ChartRenderer from './ChartRenderer';
 
const cubejsApi = cubejs('YOUR-CUBEJS-API-TOKEN', {
  apiUrl: 'http://localhost:4000/cubejs-api/v1',
});
 
const App = () => (
  <QueryBuilder
    query={{
      timeDimensions: [
        {
          dimension: 'LineItems.createdAt',
          granularity: 'month',
        },
      ],
    }}
    cubejsApi={cubejsApi}
    render={({ resultSet, measures, availableMeasures, updateMeasures }) => (
      <Layout.Content style={{ padding: '20px' }}>
        <Select
          mode="multiple"
          style={{ width: '100%' }}
          placeholder="Please select"
          onSelect={(measure) => updateMeasures.add(measure)}
          onDeselect={(measure) => updateMeasures.remove(measure)}
        >
          {availableMeasures.map((measure) => (
            <Select.Option key={measure.name} value={measure}>
              {measure.title}
            </Select.Option>
          ))}
        </Select>
        <Divider />
        {measures.length > 0 ? (
          <ChartRenderer resultSet={resultSet} />
        ) : (
          <Empty description="Select measure or dimension to get started" />
        )}
      </Layout.Content>
    )}
  />
);
 
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

QueryBuilderProps

NameTypeDescription
cubejsApi?CubejsApiCubejsApi instance to use
defaultChartType?ChartType-
defaultQuery?QueryDefault query (used when initialVizState is not set or does not contain query)
disableHeuristics?booleanDefaults to false. This means that the default heuristics will be applied. For example: when the query is empty and you select a measure that has a default time dimension it will be pushed to the query.
initialVizState?VizStateState for the QueryBuilder to start with. Pass in the value previously saved from onVizStateChanged to restore a session.
onVizStateChanged?(vizState: VizState) => voidCalled by the QueryBuilder when the viz state has changed. Use it to save state outside of the QueryBuilder component.
render(renderProps: QueryBuilderRenderProps) => React.ReactNode-
stateChangeHeuristics?(state: QueryBuilderState, newState: QueryBuilderState) => QueryBuilderStateA function that accepts the newState just before it's applied. You can use it to override the defaultHeuristics or to tweak the query or the vizState in any way.
wrapWithQueryRenderer?boolean-

QueryBuilderRenderProps

NameTypeDescription
availableDimensionsTCubeDimension[]An array of available dimensions to select. They are loaded via the API from Cube.js Backend.
availableFilterMembersArray<AvailableCube<TCubeMeasure> | AvailableCube<TCubeDimension>>-
availableMeasuresTCubeMeasure[]An array of available measures to select. They are loaded via the API from Cube.js Backend.
availableMembersAvailableMembers-
availableSegmentsTCubeSegment[]An array of available segments to select. They are loaded via the API from Cube.js Backend.
availableTimeDimensionsTCubeDimension[]An array of available time dimensions to select. They are loaded via the API from Cube.js Backend.
chartType?ChartTypeSelected chart type
dimensionsTCubeDimension & object[]-
dryRunResponse?DryRunResponse-
error?Error | null-
filtersFilterWithExtraFields & object[]-
isFetchingMetaboolean-
isQueryPresentbooleanIndicates whether the query is ready to be displayed or not
loadingState?TLoadingState-
measuresTCubeMeasure & object[]-
metaMeta | undefined-
metaError?Error | null-
metaErrorStack?string | null-
missingMembersstring[]-
orderMembersTOrderMember[]All possible order members for the query
pivotConfig?PivotConfigSee Pivot Config
queryQueryUsed to set the initial query for this component. Note that adding this prop turns this into an uncontrolled component and will only be able to execute dryRun queries. To use this component as a controlled component, use setQuery instead.
refresh() => void-
resultSet?ResultSet | null-
richMetaError?Error | null-
segmentsTCubeSegment & object[]-
timeDimensionsTimeDimensionWithExtraFields & object[]-
updateChartType(chartType: ChartType) => voidUsed for chart type update
updateDimensionsDimensionUpdater-
updateFiltersFilterUpdater-
updateMeasuresMeasureUpdater-
updateOrderOrderUpdaterUsed for query order update
updatePivotConfigPivotConfigUpdaterHelper method for pivotConfig updates
updateQuery(query: Query) => voidUsed for partial of full query update
updateSegmentsSegmentUpdater-
updateTimeDimensionsTimeDimensionUpdater-
validatedQueryQuery-

QueryBuilderState

 QueryBuilderState: VizState & object 

QueryRenderer

 QueryRenderer extends React.Component ‹QueryRendererProps›: 

<QueryRenderer /> a react component that accepts a query, fetches the given query, and uses the render prop to render the resulting data

QueryRendererProps

NameTypeDescription
cubejsApi?CubejsApiCubejsApi instance to use
loadSql?"only" | booleanIndicates whether the generated by Cube.js SQL Code should be requested. See rest-api#sql. When set to only then only the request to /v1/sql will be performed. When set to true the sql request will be performed along with the query request. Will not be performed if set to false
queries?object-
queryQuery | Query[]Analytic query. Learn more about it's format
render(renderProps: QueryRendererRenderProps) => voidOutput of this function will be rendered by the QueryRenderer
resetResultSetOnChange?booleanWhen true the resultSet will be reset to null first on every state change
updateOnlyOnStateChange?boolean-

QueryRendererRenderProps

NameType
errorError | null
loadingStateTLoadingState
resultSetResultSet | null
sqlQuerySqlQuery | null

CubeProvider

 CubeProvider: React.FC<CubeProviderProps> 

Cube.js context provider

import React from 'react';
import cubejs from '@cubejs-client/core';
import { CubeProvider } from '@cubejs-client/react';
 
const API_URL = 'https://harsh-eel.aws-us-east-2.cubecloudapp.dev';
const CUBEJS_TOKEN =
  'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.* eyJpYXQiOjE1OTE3MDcxNDgsImV4cCI6MTU5NDI5OTE0OH0.* n5jGLQJ14igg6_Hri_Autx9qOIzVqp4oYxmX27V-4T4';
 
const cubejsApi = cubejs(CUBEJS_TOKEN, {
  apiUrl: `${API_URL}/cubejs-api/v1`,
});
 
export default function App() {
  return (
    <CubeProvider cubejsApi={cubejsApi}>
      //...
    </CubeProvider>
  )
}

CubeContext

 CubeContext: Context<CubeContextProps> 

In case when you need direct access to cubejsApi you can use CubeContext anywhere in your app

import React from 'react';
import { CubeContext } from '@cubejs-client/react';
 
export default function DisplayComponent() {
  const { cubejsApi } = React.useContext(CubeContext);
  const [rawResults, setRawResults] = React.useState([]);
  const query = {
    ...
  };
 
  React.useEffect(() => {
    cubejsApi.load(query).then((resultSet) => {
      setRawResults(resultSet.rawData());
    });
  }, [query]);
 
  return (
    <>
      {rawResults.map(row => (
        ...
      ))}
    </>
  )
}

Types

AvailableCube

NameType
cubeNamestring
cubeTitlestring
membersT[]
publicboolean
type"cube" | "view"

AvailableMembers

NameType
dimensionsAvailableCube<TCubeDimension>[]
measuresAvailableCube<TCubeMeasure>[]
segmentsAvailableCube<TCubeSegment>[]
timeDimensionsAvailableCube<TCubeDimension>[]

ChartType

 ChartType: "line" | "bar" | "table" | "area" | "number" | "pie" 

CubeContextProps

NameType
cubejsApiCubejsApi
options?CubeProviderOptions

CubeProviderOptions

NameType
castNumerics?boolean

CubeProviderProps

NameType
childrenReact.ReactNode
cubejsApiCubejsApi | null
options?CubeProviderOptions

DimensionUpdater

 DimensionUpdater: MemberUpdater<TCubeDimension> 

FilterExtraFields

NameType
dimensionTCubeDimension | TCubeMeasure
operatorsobject[]

FilterUpdateFields

NameType
dimensionTCubeDimension | TCubeMeasure
member?string
operatorBinaryOperator | UnaryOperator
values?string[]

FilterUpdater

 FilterUpdater: MemberUpdater<FilterUpdateFields> 

FilterWithExtraFields

 FilterWithExtraFields: Omit<Filter, "dimension"> & FilterExtraFields 

GranularityOptions

NameType
granularitiesobject[]

MeasureUpdater

 MeasureUpdater: MemberUpdater<TCubeMeasure> 

MemberUpdater

You can use the following methods for member manipulaltion

<QueryBuilder
  // ...
  cubejsApi={cubejsApi}
  render={({
    // ...
    availableMeasures,
    updateMeasures,
  }) => {
    return (
      // ...
      <Select
        mode="multiple"
        placeholder="Please select"
        onSelect={(measure) => updateMeasures.add(measure)}
        onDeselect={(measure) => updateMeasures.remove(measure)}
      >
        {availableMeasures.map((measure) => (
          <Select.Option key={measure.name} value={measure}>
            {measure.title}
          </Select.Option>
        ))}
      </Select>
    );
  }}
/>

NOTE: if you need to add or remove more than one member at a time you should use updateQuery prop of QueryBuilderRenderProps

<QueryBuilder
  // ...
  cubejsApi={cubejsApi}
  render={({
    // ...
    measures,
    updateMeasures,
    updateQuery,
  }) => {
    // ...
    return (
      <>
        // WRONG: This code will not work properly
        <button
          onClick={() =>
            measures.forEach((measure) => updateMeasures.remove(measure))
          }
        >
          Remove all
        </button>
 
        // CORRECT: Using `updateQuery` for removing all measures
        <button
          onClick={() =>
            updateQuery({
              measures: [],
            })
          }
        >
          Remove all
        </button>
      </>
    );
  }}
/>
NameType
add(member: T) => void
remove(member: object) => void
update(member: object, updateWith: T) => void

OrderUpdater

NameType
reorder(sourceIndex: number, destinationIndex: number) => void
set(memberId: string, order: QueryOrder | "none") => void
update(order: Query["order"]) => void

PivotConfigExtraUpdateFields

NameType
limit?number

PivotConfigUpdater

NameType
moveItem(args: PivotConfigUpdaterArgs) => void
update(pivotConfig: PivotConfig & PivotConfigExtraUpdateFields) => void

PivotConfigUpdaterArgs

NameType
destinationAxisTSourceAxis
destinationIndexnumber
sourceAxisTSourceAxis
sourceIndexnumber

SegmentUpdater

 SegmentUpdater: MemberUpdater<TCubeSegment> 

TLoadingState

NameType
isLoadingboolean

TimeDimensionComparisonUpdateFields

NameType
compareDateRangeArray<DateRange>
dimensionTCubeDimension
granularity?TimeDimensionGranularity

TimeDimensionExtraFields

NameType
dimensionTCubeDimension & GranularityOptions

TimeDimensionRangedUpdateFields

NameType
dateRange?DateRange
dimensionTCubeDimension
granularity?TimeDimensionGranularity

TimeDimensionUpdater

 TimeDimensionUpdater: MemberUpdater<TimeDimensionRangedUpdateFields | TimeDimensionComparisonUpdateFields> 

TimeDimensionWithExtraFields

 TimeDimensionWithExtraFields: Omit<TimeDimension, "dimension"> & TimeDimensionExtraFields 

VizState

NameType
chartType?ChartType
pivotConfig?PivotConfig
query?Query