meliorence / react-native-render-html

iOS/Android pure javascript react-native component that renders your HTML into 100% native views
https://meliorence.github.io/react-native-render-html/
BSD 2-Clause "Simplified" License
3.48k stars 589 forks source link

React keys warning when using dangerouslyDisableWhitespaceCollapsing #562

Closed eVoloshchak closed 2 years ago

eVoloshchak commented 2 years ago

Decision Table

Good Faith Declaration

Description

I'm trying to render multiple divs with a line break between them (<div>str1</div><br /><div>str2</div><br /><div>str3</div>). Problem arises when setting dangerouslyDisableWhitespaceCollapsing prop to true, I get the following yellow box warning:

Warning: Encountered two children with the same key, 0. Keys should be unique so that components maintain their identity across updates. Non-unique keys may cause children to be duplicated and/or omitted — the behavior is unsupported and could change in a future version.

Screenshot_20220505-200319

Root cause: Library calls mapCollapsibleChildren for each child and assigns a key to it on this line:

const key = childTnode.nodeIndex;

But the problem is, TPhrasing render nodes always have a nodeIndex = 0 image

Suggested fix: Use element's index additionally to nodeIndex when assigning keys to children

const key = `${childTnode.nodeIndex}_${n}`

This ensures that every child always has a unique key image

Is this fix acceptable? Should I submit a PR?

React Native Information

System:
    OS: Linux 5.4 Linux Mint 20.3 (Una)
    CPU: (4) x64 Intel(R) Core(TM) i7-7500U CPU @ 2.70GHz
    Memory: 1.17 GB / 7.69 GB
    Shell: 5.0.17 - /bin/bash
  Binaries:
    Node: 14.9.0 - /usr/local/bin/node
    Yarn: Not Found
    npm: 6.14.8 - /usr/local/bin/npm
    Watchman: 2022.03.21.00 - /home/linuxbrew/.linuxbrew/bin/watchman
  SDKs:
    Android SDK: Not Found
  IDEs:
    Android Studio: Not Found
  Languages:
    Java: Not Found
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.2 => 17.0.2 
    react-native: 0.68.1 => 0.68.1 
  npmGlobalPackages:
    *react-native*: Not Found

RNRH Version

6.3.4

Tested Platforms

Reproduction Platforms

Minimal, Reproducible Example

Yellow box warnings seem to be disabled on snack, so I've created this git repo.

import React from 'react';
import {
  TRenderEngineProvider,
  RenderHTMLConfigProvider,
  RenderHTMLSource
} from 'react-native-render-html';

const BaseHTMLEngineProvider = (props) => {
  return (
      <TRenderEngineProvider dangerouslyDisableWhitespaceCollapsing>
          <RenderHTMLConfigProvider >
              {props.children}
          </RenderHTMLConfigProvider>
      </TRenderEngineProvider>
  );
};

const App = () => {
  const source = {
    html: `<div>str1</div><br /><div>str2</div><br /><div>str3</div>`
  };

  return (
    <BaseHTMLEngineProvider>
      <RenderHTMLSource source={source} contentWidth={500} />
    </BaseHTMLEngineProvider>
  )
};

export default App;

Additional Notes

No response