Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Watch changes without rerender #912

Closed
ali-shabani opened this issue Jan 27, 2020 · 20 comments
Closed

Watch changes without rerender #912

ali-shabani opened this issue Jan 27, 2020 · 20 comments
Labels
not valid not valid issue, question or suggestion wont be worked on This will not be worked on

Comments

@ali-shabani
Copy link

Hi, there is an option in react form hook that we can watch values change. but there is a problem with it that every time a watching variable changes a re render occur in my components. I know you have a solution in advanced part to use memozation to reduce re renders. but I want a way to listen to variables change without any re rendering. I think it should be handle by adding extra argumnet in useForm function for listening to changes. there should be a function as argument to pass to useForm to called every once a change occurs;

const form = useForm({listener});
listener(data) {
  // something like autosave form in backend
}
@bluebill1049
Copy link
Member

bluebill1049 commented Jan 27, 2020

hi, in order to get a new updated value, you will have to invoke the function in this particular example is your Component function which will leads to rendering, however, if you only want to retrieve the value of particular inputs: use getValues().

@bluebill1049 bluebill1049 added not valid not valid issue, question or suggestion wont be worked on This will not be worked on labels Jan 27, 2020
@ali-shabani
Copy link
Author

I don't mean to place listener in my component, imagine if listener is a standalone function. then invoking it won't rerender our component.

const component = () => {
  const form = useForm({listener});

  return <Anything />
}

// it can be invoke without forcing any component to rerender 
function listener(data) {
  autoSaveTobackend(data);
}

@bluebill1049
Copy link
Member

bluebill1049 commented Jan 27, 2020

you can achieve this by attach onChange on your input and invoke getValues(), I don't have any plan to grow API just yet. Thanks for your suggestion.

@bluebill1049
Copy link
Member

not going to waste this idea tho, adding to my backlog

@bluebill1049 bluebill1049 added this to To do in React Hook Form Jan 28, 2020
@FatehAK
Copy link

FatehAK commented Apr 14, 2020

Hi @bluebill1049 facing the same issue here watching a single field (an isolated child component) seems to trigger a rerender of the parent component and any other watched child components

@baba43
Copy link

baba43 commented Sep 24, 2020

I think an easy option for this would be very nice.

It's a common use-case to update some fields as soon as others have changed.

@benswinburne
Copy link

This would be really useful to me too. I've had to jump through some serious hoops to get a combination of remote loading values and autosaving fields to work because of not being able to watch for changes without rerendering/setting values without triggering watch etc.

@bluebill1049
Copy link
Member

This would be really useful to me too. I've had to jump through some serious hoops to get a combination of remote loading values and autosaving fields to work because of not being able to watch for changes without rerendering/setting values without triggering watch etc.

try useWatch, you can isolate that re-render.

@phjdreef
Copy link

phjdreef commented Dec 19, 2020

Hi,

How can I manage this?
Now I have:

  const useWatchData = useWatch({
    control,
  });

  return (
    <Fragment>
      <form id={id}>
....using {control, errors}
      </form>
    </Fragment>

It still re-renders when I use "UseWatch, something to do with the change of control/errors I think ..
With Only getValues(), it doesnt react on changing values.

@bluebill1049
Copy link
Member

Hi,

How can I manage this?
Now I have:

  const useWatchData = useWatch({
    control,
  });

  return (
    <Fragment>
      <form id={id}>
....using {control, errors}
      </form>
    </Fragment>

It still re-renders when I use "UseWatch, something to do with the change of control/errors I think ..
With Only getValues(), it doesnt react on changing values.

useWatch is for isolate re-render, not avoid re-render.

@lionskape
Copy link

Is there any ways to unsubscribe from watching values change?

@bluebill1049
Copy link
Member

Is there any ways to unsubscribe from watching values change?

until unmount.

@Noitidart
Copy link

Noitidart commented Aug 2, 2021

I'm using "react-hook-form": "^7.6.4"

When I do,

function MyComponent() {

const form = useForm();

useEffect(() => {
   form.watch((data) => {
       console.log('data:', data);
   });
}, []);

console.log('rendered');

return ........;

}

when the callback triggers, it doesnt seem a re-render happens. is this the way to make re-render not happen?

@abdo
Copy link

abdo commented Oct 2, 2021

By subscribing to watch:

`
useEffect(() => {
const subscription = watch((value, { name, type }) => console.log(value, name, type));
return () => subscription.unsubscribe();
}, [watch]);

`

@PiTiLeZarD
Copy link

useWatch did the trick to me, I pass control in the component, const data = useWatch({ control }) and only that component re-renders on updates. Perfect! I spent so much time trying to fix this in formik that I cheered when it worked with react-hook-form ;)

Thanks guys!

@gowthamvbhat
Copy link

gowthamvbhat commented Jan 14, 2022

I'm using "react-hook-form": "^7.6.4"

When I do,

function MyComponent() {

const form = useForm();

useEffect(() => {
   form.watch((data) => {
       console.log('data:', data);
   });
}, []);

console.log('rendered');

return ........;

}

when the callback triggers, it doesnt seem a re-render happens. is this the way to make re-render not happen?

I just wanted to check if the form was modified after a certain stage without needing the actual value of the fields and this worked for me!
But not sure if this comes with any pitfall

@ali-shabani
Copy link
Author

@gowthamvbhat
I don't know there is any pitfall to this or not. But there is a property named dirty in Form. You can check that to ensure if your Form has been changed or not. Just consider that dirty is false only when you initiate the Form. It became dirty and will remain dirty if any Form values change. You can use reset to clean your Form (bring back dirty to false value), and in reset, you can even keep your values with the latest changes.

@gowthamvbhat
Copy link

@ali-shabani Thanks a lot! This felt much cleaner to implement.

@metalheadcode
Copy link

not going to waste this idea tho, adding to my backlog

id like to hear an update about this..

@Upinwv
Copy link

Upinwv commented Aug 24, 2022 via email

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 23, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
not valid not valid issue, question or suggestion wont be worked on This will not be worked on
Projects
Development

No branches or pull requests