score:0

Accepted answer

the rows are updating because of the context is being updated as you type. look at the style value.

const [styles, setstyles] = react.usestate({'a':'a', 'b':'b'})
const [inneroptions, setoptions] = react.usestate({})
const value = react.usememo(() => ({options: inneroptions, styles: styles}), [styles, inneroptions]);

also the item={[]} prop on each row should be static(outside the component) or in state/memo/ref as this will also cause a rendering. im assuming this is here for simplicity.

a simple solution would be just to not use a global/root context(thats not stable) and to use memo/selectors or even something like reslect to create stable state slices for each type then using react.memo to skip rendering when props are equal. the obvious downside is that you will need to prop drill those values down and that can get annoying. and probably why you decided to go with context in the first place. here is an untested example using a memoed selector.

const row = react.memo((props) => ...); // your row component now wrapped with memo.

// im injecting styles, options, ect so that you dont have to keep this code in
// the component because it makes the component code more focused.
// you could move this into a new file, put it directly inside your component, ect. 
const selectrowtype = (type, styles, options) => {
  const style = styles[type];

  return usememo(() => {
    return { options, style };
  }, [style, options]);
};

<row type={selectrowtype('a', styles, inneroptions) items={...} />
<row type={selectrowtype('b', styles, inneroptions) items={...} />

a compromise could be to use a rowcontext inside each row that way the cells and other row children can use context values derived by the type and would be stable unless the observed type changes in the parent. you would still need to preselect the values for each row type, but would avoid the prop drilling pain inside the <row /> boundary.

const default_row_context_value = {};
const rowcontext = createcontext(default_row_context_value );

// create a stable row context value.
// we can further enrich the context with row specific data here.
const selectrowcontextvalue = (props) => {
  const { type, items } = props;

  return usememo(() => {
    return { type, items }; 
  }, [type, items]); 
}; 

const row = react.memo((props) => {
  return (
    <rowcontext.provider value={selectrowcontextvalue(props)}>
      {...}
    </rowcontext.provider>
  );  
});

<row type={selectrowtype('a', styles, inneroptions) items={...} />
<row type={selectrowtype('b', styles, inneroptions) items={...} />

if you have only <cell /> children and they arn't deep, then there really isn't a reason to use rowcontext on every <row />. it's up to you.


Related Query

More Query from same tag