Skip to content

Conversation

@alexfauquette
Copy link
Member

Extraction from #20052

Just replaced the custom store by it's common version, and adapted the codebase to it.

Selectors remain untouched. Only the useLazySelectorEffect got replaced by useStoreEffect

@alexfauquette alexfauquette added the type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature. label Oct 28, 2025
@alexfauquette alexfauquette added the scope: charts Changes related to the charts. label Oct 28, 2025
@mui-bot
Copy link

mui-bot commented Oct 28, 2025

Deploy preview: https://deploy-preview-20121--material-ui-x.netlify.app/

Bundle size report

Bundle Parsed size Gzip size
@mui/x-data-grid 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-pro 0B(0.00%) 0B(0.00%)
@mui/x-data-grid-premium 0B(0.00%) 0B(0.00%)
@mui/x-charts 🔺+100B(+0.03%) ▼-65B(-0.06%)
@mui/x-charts-pro ▼-51B(-0.01%) ▼-85B(-0.06%)
@mui/x-charts-premium ▼-72B(-0.02%) ▼-113B(-0.09%)
@mui/x-date-pickers 0B(0.00%) 0B(0.00%)
@mui/x-date-pickers-pro 0B(0.00%) 0B(0.00%)
@mui/x-tree-view 0B(0.00%) 0B(0.00%)
@mui/x-tree-view-pro 0B(0.00%) 0B(0.00%)

Details of bundle changes

Generated by 🚫 dangerJS against e5e7786

@codspeed-hq
Copy link

codspeed-hq bot commented Oct 28, 2025

CodSpeed Performance Report

Merging #20121 will improve performances by 18.11%

Comparing alexfauquette:use-store (e5e7786) with master (a46d338)

Summary

⚡ 1 improvement
✅ 12 untouched

Benchmarks breakdown

Mode Benchmark BASE HEAD Change
Simulation FunnelChart with big data amount 40.5 ms 34.3 ms +18.11%

Comment on lines 69 to 72
React.useEffect(() => {
store.update((prev) => {
const width = params.width ?? prev.dimensions.width;
const height = params.height ?? prev.dimensions.height;

return {
...prev,
dimensions: {
margin: {
top: params.margin.top,
right: params.margin.right,
bottom: params.margin.bottom,
left: params.margin.left,
},
width,
height,
propsHeight: params.height,
propsWidth: params.width,
},
};
if (isFirstRender.current) {
isFirstRender.current = false;
return;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed this was causing an additional rendering for no reason

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We got a hook you can use for this now useEffectAfterFirstRender

Comment on lines +90 to +92
if (!onHighlightedAxisChange) {
return;
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an early return to replace the skip parametter that does not exist on useStoreEffect()

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the use of useStoreEffect, like, what is it for? 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose it's for causing side-effects from store updates. This seems like a good use case: if the axis interaction changed, call the onChange callback

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ok, so listening to a update in the store.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly. When a selector value get updated, the effect gets triggered

zoomInteractionConfig: initializeZoomInteractionConfig(zoomInteractionConfig),
},
};
store.set('zoom', {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to have a "partial set" where we only provide the changed props and the behaviour provides the unchanged ones?

@romgrk

// current
set<T>(key: keyof State, value: T) {
  if (!Object.is(this.state[key], value)) {
    this.setState({ ...this.state, [key]: value });
  }
}

// partial
partial<T>(key: keyof State, value: Partial<T>) {
  this.setState({ 
    ...this.state, 
    [key]: { ...this.state[key], ...value } 
  });
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense instead to implement support for nested keys? This would become store.set('zoom.zoomInteractionConfig', etc).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't that break the selectors? If the root object doesn't change how will siblings know that the parent updated? 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation would mutate every parent object, just like it happens in your partial() example.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, yeah we could do that 😅

Then I believe that API is better indeed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might still need to update more than one prop though, so partial could still be useful 🙃

Comment on lines 69 to 72
React.useEffect(() => {
store.update((prev) => {
const width = params.width ?? prev.dimensions.width;
const height = params.height ?? prev.dimensions.height;

return {
...prev,
dimensions: {
margin: {
top: params.margin.top,
right: params.margin.right,
bottom: params.margin.bottom,
left: params.margin.left,
},
width,
height,
propsHeight: params.height,
propsWidth: params.width,
},
};
if (isFirstRender.current) {
isFirstRender.current = false;
return;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We got a hook you can use for this now useEffectAfterFirstRender

Comment on lines +90 to +92
if (!onHighlightedAxisChange) {
return;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the use of useStoreEffect, like, what is it for? 🤔

@alexfauquette alexfauquette merged commit 02ae439 into mui:master Oct 30, 2025
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

scope: charts Changes related to the charts. type: enhancement It’s an improvement, but we can’t make up our mind whether it's a bug fix or a new feature.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants