Do not mutate output of flattenStyle (#45340)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/45340

flattenStyle may return an object which is already frozen (in development), so it is incorrect to further mutate this.

Changelog: [Internal]

Reviewed By: cortinico

Differential Revision: D59515063

fbshipit-source-id: 92df158d5841988d40bcd76b861963b06dad1573
This commit is contained in:
Pieter De Baets
2024-07-09 08:26:58 -07:00
committed by Facebook GitHub Bot
parent 0733e36278
commit ef2e9410d0
2 changed files with 29 additions and 15 deletions
+17 -9
View File
@@ -8,6 +8,7 @@
* @format
*/
import type {____TextStyle_Internal as TextStyleInternal} from '../StyleSheet/StyleSheetTypes';
import type {PressEvent} from '../Types/CoreEventTypes';
import type {NativeTextProps} from './TextNativeComponent';
import type {PressRetentionOffset, TextProps} from './TextProps';
@@ -132,25 +133,32 @@ const Text: React.AbstractComponent<TextProps, TextForwardRef> =
let _selectable = selectable;
const processedStyle = flattenStyle(_style);
let processedStyle: ?TextStyleInternal = flattenStyle(_style);
if (processedStyle != null) {
let overrides: ?{...TextStyleInternal} = null;
if (typeof processedStyle.fontWeight === 'number') {
// $FlowFixMe[cannot-write]
processedStyle.fontWeight = processedStyle.fontWeight.toString();
overrides = overrides || ({}: {...TextStyleInternal});
overrides.fontWeight =
// $FlowFixMe[incompatible-cast]
(processedStyle.fontWeight.toString(): TextStyleInternal['fontWeight']);
}
if (processedStyle.userSelect != null) {
_selectable = userSelectToSelectableMap[processedStyle.userSelect];
// $FlowFixMe[cannot-write]
delete processedStyle.userSelect;
overrides = overrides || ({}: {...TextStyleInternal});
overrides.userSelect = undefined;
}
if (processedStyle.verticalAlign != null) {
// $FlowFixMe[cannot-write]
processedStyle.textAlignVertical =
overrides = overrides || ({}: {...TextStyleInternal});
overrides.textAlignVertical =
verticalAlignToTextAlignVerticalMap[processedStyle.verticalAlign];
// $FlowFixMe[cannot-write]
delete processedStyle.verticalAlign;
overrides.verticalAlign = undefined;
}
if (overrides != null) {
// $FlowFixMe[incompatible-type]
processedStyle = [processedStyle, overrides];
}
}
+12 -6
View File
@@ -10,16 +10,20 @@
'use strict';
import flattenStyle from '../../StyleSheet/flattenStyle';
import React from 'react';
const render = require('../../../jest/renderer');
const Text = require('../Text');
const React = require('react');
jest.unmock('../Text');
jest.unmock('../TextNativeComponent');
function omitRef(json) {
function omitRefAndFlattenStyle(instance) {
const json = instance.toJSON();
// Omit `ref` for forward-compatibility with `enableRefAsProp`.
delete json.props.ref;
json.props.style = flattenStyle(json.props.style);
return json;
}
@@ -27,7 +31,7 @@ describe('Text', () => {
it('default render', async () => {
const instance = await render.create(<Text />);
expect(omitRef(instance.toJSON())).toMatchInlineSnapshot(`
expect(omitRefAndFlattenStyle(instance)).toMatchInlineSnapshot(`
<RCTText
accessible={true}
allowFontScaling={true}
@@ -53,7 +57,7 @@ describe('Text compat with web', () => {
const instance = await render.create(<Text {...props} />);
expect(omitRef(instance.toJSON())).toMatchInlineSnapshot(`
expect(omitRefAndFlattenStyle(instance)).toMatchInlineSnapshot(`
<RCTText
accessible={true}
allowFontScaling={true}
@@ -119,7 +123,7 @@ describe('Text compat with web', () => {
const instance = await render.create(<Text {...props} />);
expect(omitRef(instance.toJSON())).toMatchInlineSnapshot(`
expect(omitRefAndFlattenStyle(instance)).toMatchInlineSnapshot(`
<RCTText
accessibilityLabel="label"
accessibilityState={
@@ -193,7 +197,7 @@ describe('Text compat with web', () => {
const instance = await render.create(<Text style={style} />);
expect(omitRef(instance.toJSON())).toMatchInlineSnapshot(`
expect(omitRefAndFlattenStyle(instance)).toMatchInlineSnapshot(`
<RCTText
accessible={true}
allowFontScaling={true}
@@ -208,6 +212,8 @@ describe('Text compat with web', () => {
"flex": 1,
"marginInlineStart": 10,
"textAlignVertical": "center",
"userSelect": undefined,
"verticalAlign": undefined,
}
}
/>