From b89e57353ba5d4cbceb66938e5db69e760f2b507 Mon Sep 17 00:00:00 2001 From: Parsa Salavati Date: Sun, 8 Jan 2023 22:16:30 +0330 Subject: [PATCH 1/3] Add context argument to compat/Children map api React's children api map function supports a "context" argument that we don't. See https://github.com/preactjs/preact/issues/2644. --- compat/src/Children.js | 4 ++-- compat/src/index.d.ts | 6 ++++-- compat/test/browser/Children.test.js | 12 ++++++++++++ 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/compat/src/Children.js b/compat/src/Children.js index 0295d936e8..24c9c33fb1 100644 --- a/compat/src/Children.js +++ b/compat/src/Children.js @@ -1,8 +1,8 @@ import { toChildArray } from 'preact'; -const mapFn = (children, fn) => { +const mapFn = (children, fn, context) => { if (children == null) return null; - return toChildArray(toChildArray(children).map(fn)); + return toChildArray(toChildArray(children).map(fn.bind(context))); }; // This API is completely unnecessary for Preact, so it's basically passthrough. diff --git a/compat/src/index.d.ts b/compat/src/index.d.ts index ce437a1065..45c4441e0d 100644 --- a/compat/src/index.d.ts +++ b/compat/src/index.d.ts @@ -407,11 +407,13 @@ declare namespace React { export const Children: { map( children: T | T[], - fn: (child: T, i: number) => R + fn: (child: T, i: number) => R, + context: any ): R[]; forEach( children: T | T[], - fn: (child: T, i: number) => void + fn: (child: T, i: number) => void, + context: any ): void; count: (children: preact1.ComponentChildren) => number; only: (children: preact1.ComponentChildren) => preact1.ComponentChild; diff --git a/compat/test/browser/Children.test.js b/compat/test/browser/Children.test.js index 53c0c776bf..f8d0549314 100644 --- a/compat/test/browser/Children.test.js +++ b/compat/test/browser/Children.test.js @@ -5,6 +5,7 @@ import { } from '../../../test/_util/helpers'; import { div, span } from '../../../test/_util/dom'; import React, { createElement, Children, render } from 'preact/compat'; +import sinon from 'sinon'; describe('Children', () => { /** @type {HTMLDivElement} */ @@ -106,6 +107,17 @@ describe('Children', () => { expect(serializeHtml(scratch)).to.equal('
0
'); }); + it('should propagate "this" context', () => { + const context = {}; + const spy = sinon.spy(child => child); // noop + const Foo = ({ children }) => { + return React.Children.map(children, spy, context); + }; + render(foo, scratch); + + expect(spy.thisValues[0]).to.equal(context); + }); + it('should flatten result', () => { const ProblemChild = ({ children }) => { return React.Children.map(children, child => { From bd713dc81998c3d8b75a93b140278c69ad7ceee7 Mon Sep 17 00:00:00 2001 From: Ryan Christian Date: Tue, 5 Aug 2025 22:24:44 -0500 Subject: [PATCH 2/3] test: Update test case --- compat/test/browser/Children.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compat/test/browser/Children.test.js b/compat/test/browser/Children.test.js index f8d0549314..7bc9e0855b 100644 --- a/compat/test/browser/Children.test.js +++ b/compat/test/browser/Children.test.js @@ -5,7 +5,7 @@ import { } from '../../../test/_util/helpers'; import { div, span } from '../../../test/_util/dom'; import React, { createElement, Children, render } from 'preact/compat'; -import sinon from 'sinon'; +import { vi } from 'vitest'; describe('Children', () => { /** @type {HTMLDivElement} */ @@ -109,13 +109,13 @@ describe('Children', () => { it('should propagate "this" context', () => { const context = {}; - const spy = sinon.spy(child => child); // noop + const spy = vi.fn(child => child); // noop const Foo = ({ children }) => { return React.Children.map(children, spy, context); }; render(foo, scratch); - expect(spy.thisValues[0]).to.equal(context); + expect(spy.mock.calls[0]).to.equal(context); }); it('should flatten result', () => { From 4b35d10b95e7e9b6a5a5e64a37e2abd7cd8ecdfe Mon Sep 17 00:00:00 2001 From: Ryan Christian Date: Tue, 5 Aug 2025 22:31:20 -0500 Subject: [PATCH 3/3] test: Fix mock context check --- compat/test/browser/Children.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compat/test/browser/Children.test.js b/compat/test/browser/Children.test.js index 7bc9e0855b..4f4f9434fa 100644 --- a/compat/test/browser/Children.test.js +++ b/compat/test/browser/Children.test.js @@ -115,7 +115,7 @@ describe('Children', () => { }; render(foo, scratch); - expect(spy.mock.calls[0]).to.equal(context); + expect(spy.mock.contexts[0]).to.equal(context); }); it('should flatten result', () => {