diff --git a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationHooks-test.js b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationHooks-test.js
index afd366aaa2036..65e4188dc9c44 100644
--- a/packages/react-dom/src/__tests__/ReactDOMServerIntegrationHooks-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMServerIntegrationHooks-test.js
@@ -564,7 +564,7 @@ describe('ReactDOMServerHooks', () => {
});
describe('useCallback', () => {
- itRenders('should ignore callbacks on the server', async render => {
+ itRenders('should not invoke the passed callbacks', async render => {
function Counter(props) {
useCallback(() => {
yieldValue('should not be invoked');
@@ -589,6 +589,34 @@ describe('ReactDOMServerHooks', () => {
expect(domNode.tagName).toEqual('SPAN');
expect(domNode.textContent).toEqual('Count: 5');
});
+
+ itRenders(
+ 'should only change the returned reference when the inputs change',
+ async render => {
+ function CapitalizedText(props) {
+ const [text, setText] = useState(props.text);
+ const [count, setCount] = useState(0);
+ const capitalizeText = useCallback(() => text.toUpperCase(), [text]);
+ yieldValue(capitalizeText);
+ if (count < 3) {
+ setCount(count + 1);
+ }
+ if (text === 'hello' && count === 2) {
+ setText('hello, world.');
+ }
+ return ;
+ }
+
+ const domNode = await render();
+ const [first, second, third, fourth, result] = clearYields();
+ expect(first).toBe(second);
+ expect(second).toBe(third);
+ expect(third).not.toBe(fourth);
+ expect(result).toEqual('HELLO, WORLD.');
+ expect(domNode.tagName).toEqual('SPAN');
+ expect(domNode.textContent).toEqual('HELLO, WORLD.');
+ },
+ );
});
describe('useImperativeHandle', () => {
diff --git a/packages/react-dom/src/server/ReactPartialRendererHooks.js b/packages/react-dom/src/server/ReactPartialRendererHooks.js
index 23e5af5b0c7da..ba69b1f37582b 100644
--- a/packages/react-dom/src/server/ReactPartialRendererHooks.js
+++ b/packages/react-dom/src/server/ReactPartialRendererHooks.js
@@ -456,8 +456,7 @@ export function useCallback(
callback: T,
deps: Array | void | null,
): T {
- // Callbacks are passed as they are in the server environment.
- return callback;
+ return useMemo(() => callback, deps);
}
function useResponder(responder, props): ReactEventResponderListener {