react-querybuilder / react-querybuilder

The Query Builder component for React
https://react-querybuilder.js.org/
MIT License
1.16k stars 254 forks source link

Custom input element loses focus after any character entered #153

Closed lox closed 3 years ago

lox commented 4 years ago

I'm having a problem with trying to create a custom value editor for numbers (I want to validate the number).

My understanding from reading the docs is that something like this should work:

import React from 'react';

const ValueEditor = ({ handleOnChange, value }) => (
  <input type="text" onChange={(e) => handleOnChange(e.target.value)} value={value} />
);
const App = () => (
  <QueryBuilder
    fields={[{ name: "test", label: "Test" }]}
    controlElements={{ valueEditor: ValueEditor }}
  />
);

//...

Which appears to work fine, but when I type in the input it loses focus after each keystroke.

Any suggestions?

jakeboone02 commented 4 years ago

@lox can you set up a codesandbox reproducing the issue?

charliedieter commented 3 years ago

Same here, but only when I am updating the parent component state onQueryChange - it seems to be because the parent state is updating, re-rendering the input on every change. I have yet to find a solution.

jakeboone02 commented 3 years ago

@lox / @CharlieDieter, I was able to reproduce the issue in this codesandbox. The problem occurs when you define the ValueEditor within the App component. That causes the ValueEditor to be re-instantiated each time App renders, which happens on each keystroke for a controlled component like that.

The solution is to define ValueEditor outside of the scope of App like in your example.

If that doesn't help, or that wasn't the actual issue, please set up a codesandbox example demonstrating the problem.

urjit0204 commented 3 years ago

Can anyone find a solution? I am facing the same issue and, I have not got any solution yet. @jakeboone02 @lox

jakeboone02 commented 3 years ago

@urjit0204 can you reproduce your issue in a codesandbox? AFAICT, the only way to reproduce the behavior is to define the ValueEditor component within the App component, as I described above and in this codesandbox.

amitdhiman000 commented 3 years ago

@jakeboone02 I looked at the workaround you told. I moved my ValueEditor component out to main component and it works. But in my case I need to send some extra props to ValueEditor component. e.g. singlevalue/multivalue input or view/create/edit mode. How we can achieve that? If I try closure using arrow function or bind(), same problem again persists. for reference: codesandbox

jakeboone02 commented 3 years ago

@amitdhiman000 I believe I've fixed your issue with this codesandbox. You can pass arbitrary parameters in through the fieldData prop. Just add the parameters to the fields array objects and they will be passed through to the ValueEditor.

amitdhiman000 commented 3 years ago

@jakeboone02 This solution will work for the fields. how about +Rule +Group, buttons. I wanted to show these button in disabled state. Can't we add some extra props to QueryBuilder itself, which will be available in all callbacks.

jakeboone02 commented 3 years ago

@amitdhiman000 that's a good idea. I'll close this ticket and put something together for a way to pass arbitrary props to the custom components.

jakeboone02 commented 3 years ago

@amitdhiman000 your idea was implemented in v3.9.0 as a context prop which can contain anything (it's type any) and will be passed to all custom components.

amitdhiman000 commented 3 years ago

@jakeboone02 that is great news. I appreciate your efforts. Thanks you.