Skip to content

Commit

Permalink
Add: Add a usePreviousValue hook
Browse files Browse the repository at this point in the history
Add a new hooks that allows to get the previous value after the value is
changed. For example this hook can be used to check whether a filter has
changed.
  • Loading branch information
bjoernricks committed Jun 7, 2024
1 parent 3371ec5 commit 3c1d85e
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 0 deletions.
41 changes: 41 additions & 0 deletions src/web/hooks/__tests__/usePreviousValue.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/* SPDX-FileCopyrightText: 2024 Greenbone AG
*
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import {useState} from 'react';

import {describe, test, expect} from '@gsa/testing';

import {fireEvent, render, screen} from 'web/utils/testing';

import usePreviousValue from '../usePreviousValue';

const TestComponent = () => {
const [value, setValue] = useState(0);
const previousValue = usePreviousValue(value);
return (
<>
<button onClick={() => setValue(1)}></button>
<span data-testid="value">{value}</span>
<span data-testid="previousValue">{'' + previousValue}</span>
</>
);
};

describe('usePreviousValue', () => {
test('should return the previous value', () => {
render(<TestComponent />);

const value = screen.getByTestId('value');
const previousValue = screen.getByTestId('previousValue');

expect(value).toHaveTextContent('0');
expect(previousValue).toHaveTextContent('undefined');

fireEvent.click(screen.getByRole('button'));

expect(value).toHaveTextContent('1');
expect(previousValue).toHaveTextContent('0');
});
});
35 changes: 35 additions & 0 deletions src/web/hooks/usePreviousValue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/* SPDX-FileCopyrightText: 2024 Greenbone AG
*
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import {useEffect, useRef} from 'react';

/**
* React custom hook to store the value of the previous rendering
*
* It allows for checking if a value has changed since last render.
*
* Code Snippet
*
* ```
* const [value, setValue] = useState(initialValue);
* const previousValue = usePrevious(value);
*
* if (value !== previousValue) { // value has changed
* doSomething()
* }
* ```
*/
const usePreviousValue = value => {
const ref = useRef(); // initially the previous value is undefined

useEffect(() => {
// will be called AFTER the calling component has rendered
ref.current = value;
});

return ref.current;
};

export default usePreviousValue;

0 comments on commit 3c1d85e

Please sign in to comment.