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

feat: new hook useGetSet #530

Closed
wants to merge 3 commits into from
Closed

Conversation

fengkx
Copy link
Contributor

@fengkx fengkx commented Dec 14, 2021

What new hook does?

Port of useGetSet in react-use

Checklist

  • Have you read contribution guideline?
  • Does the code have comments in hard-to-understand areas?
  • Is there an existing issue for this PR?
    Port remaining hooks from react-use #33
  • Have the files been linted and formatted?
  • Have the docs been updated?
  • Have the tests been added to cover new hook?
  • Have you run the tests locally to confirm they pass?

@codecov
Copy link

codecov bot commented Dec 14, 2021

Codecov Report

Merging #530 (13c374c) into master (c79d007) will not change coverage.
The diff coverage is 100.00%.

❗ Current head 13c374c differs from pull request most recent head a05d0ae. Consider uploading reports for the commit a05d0ae to get more accurate results
Impacted file tree graph

@@            Coverage Diff            @@
##            master      #530   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           44        45    +1     
  Lines          776       788   +12     
  Branches       138       138           
=========================================
+ Hits           776       788   +12     
Impacted Files Coverage Δ
src/index.ts 100.00% <100.00%> (ø)
src/useGetSet/useGetSet.ts 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c79d007...a05d0ae. Read the comment docs.

},
[rerender]
);
return [get, set];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not to use useSafeState, useSyncedRef and useCallback?

Besides this code will work - id prefer native state holder

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I don't understand here.

id prefer native state holder

what is it means here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

either useState nor useSafeState update the value immediately. That why this hook is need and useRerender is used in setter to control UI updates.

How useSyncedRef can be used here

Copy link
Contributor

@xobotyi xobotyi Dec 16, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implementation breaks 'state flow' of react, and will break in strict mode, 4ex.

What i propose is to implement hook like this:

export function useGetSet<S>(
  initialState: IInitialState<S>
): [get: () => S, set: Dispatch<SetStateAction<S>>] {
  const [state, setState] = useSafeState(initialState);
  const stateRef = useSyncedRef(state);

  // eslint-disable-next-line react-hooks/exhaustive-deps
  return [useCallback(() => stateRef.current, []), setState];
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This implementation doesn't return latest value in getter. /

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make sense to me

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But how to write test, since I don't know when will react state change

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wrap all set calls with act method of testing library.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, PR lack of readme changes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just wrap all set calls with act method of testing library.

  it('should set new value', () => {
    const { result } = setUp('foo');
    const [get, set] = result.current;
    act(() => set('bar'));
    const currentValue = get();
    expect(currentValue).toBe('bar');
  });

This test cannot pass /


act(() => {
jest.runAllTimers();
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is way overcomplicated, why not to simply set state inside act?

act(()=>{
 set();
 set();
 set();
})

@xobotyi xobotyi added 🎂 new hook New hook added 👎 invalid This doesn't seem right labels Mar 8, 2022
@xobotyi xobotyi mentioned this pull request Jun 30, 2022
7 tasks
@xobotyi xobotyi closed this in #862 Jun 30, 2022
@xobotyi
Copy link
Contributor

xobotyi commented Jun 30, 2022

🎉 This issue has been resolved in version 14.7.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
👎 invalid This doesn't seem right 🎂 new hook New hook added released
Development

Successfully merging this pull request may close these issues.

2 participants