react-native-windows
react-native-windows copied to clipboard
Various bugs and crashes related to fast text workaround
Problem Description
In TextViewManager, we special case a <Text> component with a single raw text (Run) child by setting the TextBlock::Text
property directly, rather than adding an inline to allow XAML to perform optimized text rendering.
The current implementation has a few bugs:
- Prepending raw text at index 0 to a view that has other inline children drops all other inline children
- Attempting to unmount any other inline after prepending raw text at index 0 causes the app to crash due to the TextBlock::InlineCollection being empty / owned by the overwritten TextBlock::Text property
- Prepending virtual text (Span) at index 0 to a view that is optimized for fast text works, but when unmounting the prepended virtual text, it also removes the raw text.
- Prepending virtual text (Span) at index 0 to a view that is optimized for fast text works, but when unmounting the raw text then attempting to add a raw text node back at index 1, the app crashes.
Steps To Reproduce
Run the scenarios described above with the following example:
export default function App() {
const [addRawText, setAddRawText] = useState(false);
const [appendVirtualText, setAppendVirtualText] = useState(true);
const [prependVirtualText, setPrependVirtualText] = useState(false);
return (
<View>
<View>
<Text>{prependVirtualText ? <Text>1{' '}</Text> : null}{addRawText ? "2 " : null}{appendVirtualText ? <Text>3</Text> : null}</Text>
</View>
<View onTouchEnd={() => setPrependVirtualText(!prependVirtualText)}>
<Text>{prependVirtualText ? 'Remove Prepended' : 'Prepend'} Virtual Text {'(1)'}</Text>
</View>
<View onTouchEnd={() => setAddRawText(!addRawText)}>
<Text>{addRawText ? 'Remove' : 'Insert'} Raw Text {'(2)'}</Text>
</View>
<View onTouchEnd={() => setAppendVirtualText(!appendVirtualText)}>
<Text>{appendVirtualText ? 'Remove Appended' : 'Append'} Virtual Text {'(3)'}</Text>
</View>
</View>
)
}
Expected Results
App should behave correctly when appending / prepending raw text / virtual text in the scenarios above. I.e.,
- Text should read "2 3"
- App should not crash and text should read "2"
- Text should read "2"
- App should not crash and text should read "1 2"
CLI version
npx react-native --version
Environment
npx react-native info
Target Platform Version
No response
Target Device(s)
No response
Visual Studio Version
No response
Build Configuration
No response
Snack, code example, screenshot, or link to a repository
No response