Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve diffing of styles #566

Merged
merged 1 commit into from Mar 26, 2023
Merged

Improve diffing of styles #566

merged 1 commit into from Mar 26, 2023

Conversation

vadimdemedes
Copy link
Owner

@vadimdemedes vadimdemedes commented Mar 26, 2023

Problem

style property of Ink nodes contains the changed fields of style object, rather than a full style object itself. As a result, style in internal representation of an Ink node is inconsistent what's actually passed via a style prop to ink-box (rendered by Box) or ink-text (rendered by Text).

Here's example code demonstrating the problem:

const {rerender} = render(<Box borderStyle="round" borderColor="green"/>);
// Box's style = { borderStyle: 'round', borderColor: 'green' }
// Ink node's style = { borderStyle: 'round', borderColor: 'green' }

rerender(<Box borderStyle="round" borderColor="blue"/>);
// Box's style = { borderStyle: 'round', borderColor: 'blue' }
// Ink node's style = { borderColor: 'blue' }

borderStyle hasn't been changed between renders, so it's no longer present in the internal style object. This led to #345, which actually didn't have a proper solution to the root problem (style being out of sync), but rather a workaround that special-cased props like borderStyle to always be present in the style object.

Solution

This PR does several things to remove this workaround I shipped before:

  1. Make setStyle function responsible for only setting styles and not updating Yoga node.
  2. Change reconciler's prepareUpdate to diff props and props.style prop separately.
  3. Skip update entirely if props or props.style hasn't changed. It's actually unrelated to this PR, but still a nice improvement.
  4. Reconciler is now the one who updates styles of a Yoga node, not setStyle function.

With this update, style is always consistent between an internal representation of an Ink node and what's passed via style prop to a React component. At the same time, reconciler still updates Yoga node with styles that were changed since last render.

@vadimdemedes vadimdemedes merged commit 690d48c into master Mar 26, 2023
6 checks passed
@vadimdemedes vadimdemedes deleted the neat-robin branch March 26, 2023 20:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant