You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi, I'm new to Solid and feel like I'm not thinking about this right. Thanks!
Setup
Let's say I'm making a 'leaderboard' for companies with the highest market cap.
I have two stores:
typeCompany={ticker: string;numShares: number}// Create the store outside of any componentconst[companies,setCompanies]=createStore({AAPL: {ticker: "AAPL",numShares: 1000},MSFT: {ticker: "MSFT",numShares: 2000},});const[stockPrices,setStockPrices]=createStore({AAPL: 150,MSFT: 250,});
I have a function which computes the market cap of each company:
typeCompanyMarketCap={company: Company;marketCap: number}functiongetMarketCaps(): CompanyMarketCap[]{// 'join' between companies & share pricesreturnObject.keys(companies).map((ticker)=>{constcompany=companies[ticker];conststockPrice=stockPrices[ticker];constmarketCap=company.numShares*stockPrice;// PROBLEM: new object created here, breaking `For`'s referential equality checkreturn{
company,
marketCap,};});}
And I have events arriving over a web socket, which could either
update the list of companies (e.g. adding a new company)
or update the stock price for a company
When these arrive, I'm updating the relevant store.
Question
How can I do this without ExpensiveWidget being re-rendered every time I recieve an event over my socket? E.g. if it's some non-Solid chart widget that has lots of internal state?
What happens now seems to be:
Event received
One of the two stores is updated
ViewMarketCaps rerenders
getMarketCaps runs again; It does its 'join' between companies and share prices
Every object returned is new; causing For to re-render each of its children because it does referential equality
ExpensiveComponent of each child rerenders, causing my UI to flicker and state to be lost
Possible Solutions I Can See
Consolidate into one store: have one store for market caps, instead of separate ones for companies and share prices.
Then, we wouldn't need to do a join which creates new objects.
I'd prefer to keep my data 'normalized' in stores until rendering, so that responsibility is cleanly separated between (a) the code that receives the events and updates the stores, and (b) the code that renders stuff based on what the user is looking at.
However, if this is what's needed, I think I can do it.
Use Keyed: don't worry about maintaining referential equality; just try to use keys to prevent rerendering
I think for me, the root issue is that in React (where I'm coming from), it's cool to write functions to do arbitrary data transformations, and then have components like
where React will match components and data up by key, and ChildComponent can make a determination of the extent to which it has to rerender its child components… But solid is big on in-place updates of data objects, so For blows away all child component state if the objects it's going over aren't referentially equal.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Hi, I'm new to Solid and feel like I'm not thinking about this right. Thanks!
Setup
Let's say I'm making a 'leaderboard' for companies with the highest market cap.
I have two stores:
I have a function which computes the market cap of each company:
And I have one view:
And I have events arriving over a web socket, which could either
When these arrive, I'm updating the relevant store.
Question
How can I do this without
ExpensiveWidget
being re-rendered every time I recieve an event over my socket? E.g. if it's some non-Solid chart widget that has lots of internal state?What happens now seems to be:
ViewMarketCaps
rerendersgetMarketCaps
runs again; It does its 'join' between companies and share pricesFor
to re-render each of its children because it does referential equalityExpensiveComponent
of each child rerenders, causing my UI to flicker and state to be lostPossible Solutions I Can See
Keyed
: don't worry about maintaining referential equality; just try to use keys to prevent rerenderingI think for me, the root issue is that in React (where I'm coming from), it's cool to write functions to do arbitrary data transformations, and then have components like
where React will match components and data up by key, and
ChildComponent
can make a determination of the extent to which it has to rerender its child components… But solid is big on in-place updates of data objects, soFor
blows away all child component state if the objects it's going over aren't referentially equal.Is there an approach I'm missing? Thanks!
Beta Was this translation helpful? Give feedback.
All reactions