Skip to main content
Version: 4.xx.xx

FAQ

How can I change the form data before submitting it to the API?

You may need to modify the form data before it is sent to the API.

For example, Let's send the values we received from the user in two separate inputs, name and surname, to the API as fullName.

import React, { useState } from 'react'
import { useForm } from '@refinedev/core'

export const UserCreate: React.FC = () => {
const [name, setName] = useState()
const [surname, setSurname] = useState()

const { onFinish } = useForm()

const onSubmit = (e) => {
e.preventDefault()
const fullName = `${name} ${surname}`
onFinish({
fullName: fullName,
name,
surname,
})
}

return (
<form onSubmit={onSubmit}>
<input onChange={(e) => setName(e.target.value)} />
<input onChange={(e) => setSurname(e.target.value)} />
<button type="submit">Submit</button>
</form>
)
}

How can I refetch data?

Refine automatically invalidates the affected resources after mutations. However, in some cases you may want to refetch manually.

import { useTable, useForm, useShow } from "@refinedev/core";

// All "data" related hooks provided by Refine can use queryResult' refetch function
const { tableQueryResult: { refetch } } = useTable();
const { queryResult: { refetch } } = useForm();
...
...
const { queryResult: { refetch } } = useShow();
...
...

How can I request an API with nested route?

Refine's way of doing this is with the resource property on all data hooks. You can think of the resource property as the URL.

For example, If you want to make a request of the URL /user/1/posts.

import { useTable, useOne } from '@refinedev/core'

useTable({
resource: '/users/1/posts',
})

How can I ensure a query is only run after a certain variable is available and not on load?

Note that data related hooks (useMany, useOne, etc.) can also accept all useQuery options, which allows you to implement dependent queries whereby a query is only run after a certain data is available. This is particularly useful if you want useMany to only run after a certain data is available and not on load.

Refer to react-query docs on dependent queries for more information →

  • Suppose you want this query to run after categoryIds is fetched by a preceding query, you can set enabled to categoryIds.length > 0. This will ensure that useMany is only run after categoryIds is fetched.
useMany({
resource: 'categories',
ids: categoryIds,
queryOptions: { enabled: categoryIds.length > 0 },
})

Can I work with JavaScript?

Yes! You can work with JavaScript!

Refer to Refine JavaScript example →

How I can override specific function of Data Providers?

In some cases, you may need to override functions of Refine data providers. The simplest way to do this is to use the Spread syntax

For example, Let's override the update function of the @refinedev/simple-rest. @refinedev/simple-rest uses the PATCH HTTP method for update, let's change it to PUT without forking the whole data provider.

import dataProvider from '@refinedev/simple-rest'

const simpleRestProvider = dataProvider('API_URL')
const myDataProvider = {
...simpleRestProvider,
update: async ({ resource, id, variables }) => {
const url = `${apiUrl}/${resource}/${id}`

const { data } = await httpClient.put(url, variables)

return {
data,
}
},
}

;<Refine dataProvider={myDataProvider} />

What if we want to select PUT or PATCH on a request basis?

💥 We can use meta for this. Remember, meta can be used in all data, form and table hooks

// PATCH Request
useUpdate({
resource: 'this-is-patch',
id: 1,
variables: {
foo: 'bar',
},
meta: {
httpMethod: 'patch',
},
})

// PUT Request
useUpdate({
resource: 'this-is-put',
id: 1,
variables: {
foo: 'bar',
},
meta: {
httpMethod: 'put',
},
})

const simpleRestProvider = dataProvider('API_URL')
const myDataProvider = {
...simpleRestProvider,
update: async ({ resource, id, variables, meta }) => {
const method = meta.httpMethod ?? 'patch'

const url = `${apiUrl}/${resource}/${id}`

const { data } = await httpClient[method](url, variables)

return {
data,
}
},
}

Why are API calls triggering twice

This is the expected behavior if you use <React.StrictMode>. In this mode, React will render the components twice in development mode to identify unsafe life cycles, unexpected side effects, and legacy or deprecated APIs. It's used for highlighting possible problems.

note

<React.StrictMode> checks are run in development mode only; they do not impact the production build.

Refer to <React.StrictMode> documentation for more information. &#8594

Refer to TanStack Query issue for more information. &#8594

How can I add an item to the Sider component?

There are three ways to add an extra navigation link to the sider.

The first and simplest way is to use the resources property on the <Refine> component. The <Sider> component shows the resources whose list property is set. So, you can have an extra navigation link by adding a resource with the list attribute.

import { Refine } from "@refinedev/core";

<Refine
...
resources={[
{
name: "dashboard",
list: "/",
meta: {
label: "Dashboard",
icon: "🏠",
},
},
]}
/>;

The second way is to use the render property of the <Sider> component. The render property is a function that receives an object with the items and logout properties. The items property is the list of navigation items and the logout property is the logout button.

import { Layout, Sider } from '@refinedev/antd'

const CustomSider = () => {
return (
<Sider
render={({ items, logout }) => {
return (
<>
<a href="https://refine.dev/">👋 Navigation Link</a>
{items}
{logout}
</>
)
}}
/>
)
}

const CustomLayout = () => {
return <Layout Sider={CustomSider}>...</Layout>
}

The third way is to use the swizzle command.

You can use the command to copy the default Sider component to your project. This will allow you to customize the sider as you want.

Refer to the swizzle documentation for more information. &#8594