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 ebff341dfd..30e4a12633 100644 --- a/compat/src/index.d.ts +++ b/compat/src/index.d.ts @@ -135,8 +135,11 @@ declare namespace React { interface MutableRefObject { current: T; } - - export type ForwardedRef = ((instance: T | null) => void) | MutableRefObject | null; + + export type ForwardedRef = + | ((instance: T | null) => void) + | MutableRefObject + | null; export function unstable_batchedUpdates( callback: (arg?: any) => void, @@ -144,17 +147,19 @@ declare namespace React { ): void; export type PropsWithChildren

= P & { - children?: preact.ComponentChild | undefined + children?: preact.ComponentChild | undefined; }; - + 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: preact.ComponentChildren) => number; only: (children: preact.ComponentChildren) => preact.ComponentChild; diff --git a/compat/test/browser/Children.test.js b/compat/test/browser/Children.test.js index 4e0c32d3b0..bd459a84ae 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 => {