@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
Name | Type | Description |
---|---|---|
castNumerics? | boolean | If enabled, all members of the 'number' type will be automatically converted to numerical values on the client side |
cubejsApi? | CubejsApi | A CubejsApi instance to use. Taken from the context if the param is not passed |
resetResultSetOnChange? | boolean | When true the resultSet will be reset to null first |
skip? | boolean | Query execution will be skipped when skip is set to true . You can use this flag to avoid sending incomplete queries. |
subscribe? | boolean | Use continuous fetch behavior. See Real-Time Data Fetch |
UseCubeQueryResult
Name | Type |
---|---|
error | Error | null |
isLoading | boolean |
progress | ProgressResponse |
refetch | () => Promise<void> |
resultSet | ResultSet<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
Name | Type | Description |
---|---|---|
cubejsApi? | CubejsApi | CubejsApi instance to use |
defaultChartType? | ChartType | - |
defaultQuery? | Query | Default query (used when initialVizState is not set or does not contain query) |
disableHeuristics? | boolean | Defaults 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? | VizState | State for the QueryBuilder to start with. Pass in the value previously saved from onVizStateChanged to restore a session. |
onVizStateChanged? | (vizState: VizState) => void | Called 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) => QueryBuilderState | A 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
Name | Type | Description |
---|---|---|
availableDimensions | TCubeDimension[] | An array of available dimensions to select. They are loaded via the API from Cube.js Backend. |
availableFilterMembers | Array<AvailableCube<TCubeMeasure> | AvailableCube<TCubeDimension>> | - |
availableMeasures | TCubeMeasure[] | An array of available measures to select. They are loaded via the API from Cube.js Backend. |
availableMembers | AvailableMembers | - |
availableSegments | TCubeSegment[] | An array of available segments to select. They are loaded via the API from Cube.js Backend. |
availableTimeDimensions | TCubeDimension[] | An array of available time dimensions to select. They are loaded via the API from Cube.js Backend. |
chartType? | ChartType | Selected chart type |
dimensions | TCubeDimension & object[] | - |
dryRunResponse? | DryRunResponse | - |
error? | Error | null | - |
filters | FilterWithExtraFields & object[] | - |
isFetchingMeta | boolean | - |
isQueryPresent | boolean | Indicates whether the query is ready to be displayed or not |
loadingState? | TLoadingState | - |
measures | TCubeMeasure & object[] | - |
meta | Meta | undefined | - |
metaError? | Error | null | - |
metaErrorStack? | string | null | - |
missingMembers | string[] | - |
orderMembers | TOrderMember[] | All possible order members for the query |
pivotConfig? | PivotConfig | See Pivot Config |
query | Query | Used 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 | - |
segments | TCubeSegment & object[] | - |
timeDimensions | TimeDimensionWithExtraFields & object[] | - |
updateChartType | (chartType: ChartType) => void | Used for chart type update |
updateDimensions | DimensionUpdater | - |
updateFilters | FilterUpdater | - |
updateMeasures | MeasureUpdater | - |
updateOrder | OrderUpdater | Used for query order update |
updatePivotConfig | PivotConfigUpdater | Helper method for pivotConfig updates |
updateQuery | (query: Query) => void | Used for partial of full query update |
updateSegments | SegmentUpdater | - |
updateTimeDimensions | TimeDimensionUpdater | - |
validatedQuery | Query | - |
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
Name | Type | Description |
---|---|---|
cubejsApi? | CubejsApi | CubejsApi instance to use |
loadSql? | "only" | boolean | Indicates 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 | - |
query | Query | Query[] | Analytic query. Learn more about it's format |
render | (renderProps: QueryRendererRenderProps) => void | Output of this function will be rendered by the QueryRenderer |
resetResultSetOnChange? | boolean | When true the resultSet will be reset to null first on every state change |
updateOnlyOnStateChange? | boolean | - |
QueryRendererRenderProps
Name | Type |
---|---|
error | Error | null |
loadingState | TLoadingState |
resultSet | ResultSet | null |
sqlQuery | SqlQuery | 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
Name | Type |
---|---|
cubeName | string |
cubeTitle | string |
members | T[] |
public | boolean |
type | "cube" | "view" |
AvailableMembers
Name | Type |
---|---|
dimensions | AvailableCube<TCubeDimension>[] |
measures | AvailableCube<TCubeMeasure>[] |
segments | AvailableCube<TCubeSegment>[] |
timeDimensions | AvailableCube<TCubeDimension>[] |
ChartType
ChartType: "line" | "bar" | "table" | "area" | "number" | "pie"
CubeContextProps
Name | Type |
---|---|
cubejsApi | CubejsApi |
options? | CubeProviderOptions |
CubeProviderOptions
Name | Type |
---|---|
castNumerics? | boolean |
CubeProviderProps
Name | Type |
---|---|
children | React.ReactNode |
cubejsApi | CubejsApi | null |
options? | CubeProviderOptions |
DimensionUpdater
DimensionUpdater: MemberUpdater<TCubeDimension>
FilterExtraFields
Name | Type |
---|---|
dimension | TCubeDimension | TCubeMeasure |
operators | object[] |
FilterUpdateFields
Name | Type |
---|---|
dimension | TCubeDimension | TCubeMeasure |
member? | string |
operator | BinaryOperator | UnaryOperator |
values? | string[] |
FilterUpdater
FilterUpdater: MemberUpdater<FilterUpdateFields>
FilterWithExtraFields
FilterWithExtraFields: Omit<Filter, "dimension"> & FilterExtraFields
GranularityOptions
Name | Type |
---|---|
granularities | object[] |
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>
</>
);
}}
/>
Name | Type |
---|---|
add | (member: T) => void |
remove | (member: object) => void |
update | (member: object, updateWith: T) => void |
OrderUpdater
Name | Type |
---|---|
reorder | (sourceIndex: number, destinationIndex: number) => void |
set | (memberId: string, order: QueryOrder | "none") => void |
update | (order: Query["order"]) => void |
PivotConfigExtraUpdateFields
Name | Type |
---|---|
limit? | number |
PivotConfigUpdater
Name | Type |
---|---|
moveItem | (args: PivotConfigUpdaterArgs) => void |
update | (pivotConfig: PivotConfig & PivotConfigExtraUpdateFields) => void |
PivotConfigUpdaterArgs
Name | Type |
---|---|
destinationAxis | TSourceAxis |
destinationIndex | number |
sourceAxis | TSourceAxis |
sourceIndex | number |
SegmentUpdater
SegmentUpdater: MemberUpdater<TCubeSegment>
TLoadingState
Name | Type |
---|---|
isLoading | boolean |
TimeDimensionComparisonUpdateFields
Name | Type |
---|---|
compareDateRange | Array<DateRange> |
dimension | TCubeDimension |
granularity? | TimeDimensionGranularity |
TimeDimensionExtraFields
Name | Type |
---|---|
dimension | TCubeDimension & GranularityOptions |
TimeDimensionRangedUpdateFields
Name | Type |
---|---|
dateRange? | DateRange |
dimension | TCubeDimension |
granularity? | TimeDimensionGranularity |
TimeDimensionUpdater
TimeDimensionUpdater: MemberUpdater<TimeDimensionRangedUpdateFields | TimeDimensionComparisonUpdateFields>
TimeDimensionWithExtraFields
TimeDimensionWithExtraFields: Omit<TimeDimension, "dimension"> & TimeDimensionExtraFields
VizState
Name | Type |
---|---|
chartType? | ChartType |
pivotConfig? | PivotConfig |
query? | Query |