Skip to main content
Version: v4

Common mistakes

Custom component as closure

A common mistake when defining custom components for React Query Builder is to define them within the body of another function component, like this:

App.tsx
const App = () => {
// Other stuff ...

const CustomValueEditor = props => {
// Custom logic here ...
return <input />;
};

return (
<QueryBuilder
fields={fields}
query={query}
handleOnChange={q => setQuery(q)}
controlElements={{
valueEditor: CustomValueEditor,
}}
/>
);
};

This can lead to undesirable behavior, such as the value editor losing focus after each keystroke. This happens because the CustomValueEditor component is being redefined each time the App component renders. To fix the problem, move the custom component declaration outside of the other function component (it can still be in the same file, just not within the function body):

App.tsx
const CustomValueEditor = props => {
// Custom logic here ...
return <input />;
};

const App = () => {
// Other stuff ...

return (
<QueryBuilder
fields={fields}
query={query}
handleOnChange={q => setQuery(q)}
controlElements={{
valueEditor: CustomValueEditor,
}}
/>
);
};