1

My main functional component performs a huge amount of useQueries and useMutations on the child component hence I have set it as React.memo so as to not cause re-rendering on each update. Basically, when new products are selected I still see the old products because of memo.

mainFunction.js

const [active, setActive] = useState(false);
const handleToggle = () => setActive(false);

const handleSelection = (resources) => {
        const idsFromResources = resources.selection.map((product) => product.variants.map(variant => variant.id));
        store.set('bulk-ids', idsFromResources); //loal storage js-store library
        handleToggle
    };
    
const emptyState = !store.get('bulk-ids'); // Checks local storage using js-store library
    
return (
    <Page>
        <TitleBar
            title="Products"
            primaryAction={{
                content: 'Select products',
                onAction: () => {
                    setActive(!active)
                }
            }}
        />
        <ResourcePicker
            resourceType="Product"
            showVariants={true}
            open={active}
            onSelection={(resources) => handleSelection(resources)}
            onCancel={handleToggle}
        />
        <Button >Add Discount to Products</Button> //Apollo useMutation

        {emptyState ? (
            <Layout>
                Select products to continue
            </Layout>
        ) : (
                <ChildComponent />
            )}
    </Page>
    );
    
    

ChildComponent.js

class ChildComponent extends React {
    return(
        store.get(bulk-ids).map((product)=>{
            <Query query={GET_VARIANTS} variables={{ id: variant }}>
                {({ data, extensions, loading, error }) => {
                    <Layout>
                        // Query result UI
                    <Layout>
                }}
            </Query>
        })
    )
}
export deafult React.memo(ChildComponent);
    
Sarun UK
  • 6,210
  • 7
  • 23
  • 48
Ashish
  • 31
  • 2
  • 7
  • If new products are set it still has to render, what it has to do with React.memo? Do you have a reproducible example? [How to create a Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) – Dennis Vash Nov 14 '20 at 13:14
  • It's not clear what happens when new products are selected. Consider to provide more details, like implementation of child component and calling of memo function. – Ken Bekov Nov 14 '20 at 13:27
  • I have updated the code – Ashish Nov 14 '20 at 14:05
  • `React.memo` freezes your component. You have to pass `bulk-ids` from parent component. Is `bulk-ids` always the same until new product is selected? – Ken Bekov Nov 14 '20 at 15:12

1 Answers1

1

React.memo() is useful when your component always renders the same way with no changes. In your case you need to re-render <ChildComponent> every time bulk-id changes. So you should use useMemo() hook.

function parentComponent() {
 
    ... rest of code

    const bulkIds = store.get('bulk-ids');
    const childComponentMemo = useMemo(() => <ChildComponent ids={bulkIds}/>, [bulkIds]); 

    return <Page>
        
        ... rest of render
        
        {bulkIds ? 
            childComponentMemo
        :(
            <Layout>
                Select products to continue
            </Layout>
        )}        
    </Page>
    
}

useMemo() returns the same value until buldIds has not changed. More details about useMemo() you can find here.

Ken Bekov
  • 13,696
  • 3
  • 36
  • 44