My parent component handles requests to the server and provides its child-components with data from the response. One child-component (FilterSidebar
: contains filter components) should in that case only be rendered once, because the filters will be created from the initial requested data.
This is why I want to use React's memo hook. The according data is only passed once to the filter-component. The log inside the areEqual
function is never called, and the component will always render again.
Parent component:
import React, { useState, useRef } from "react";
import { useQuery } from '@apollo/react-hooks';
import { REQUEST_INQUIRIES } from './requests/REQUEST_INQURIES.js'
import Canvas from './components/Canvas.js';
import FilterSidebar from './components/filter/FilterSidebar.js';
import Loader from './components/Loader.js'
import QueryContext from './components/filter/query-context.js'
const App = () => {
const [query, setQuery] = useState(["{\"name\": {\"$LIKE\": \"%\"}}"])
// used to create filters once with initial data
const [keys, setKeys] = useState([])
const [values, setValues] = useState([])
const ref = useRef(false);
const { loading, data, error } = useQuery(REQUEST_INQUIRIES, {
variables: { filters: `{ \"$AND\": [ ${query.map(q => { return q})} ]}` }
})
const addQuery = (queryPart) => {
if (!query.includes(queryPart)) setQuery(prevState => [...prevState, queryPart])
}
const contextValue = { query, addQuery }
// return loading animation here
if (loading) { return <Loader /> }
// return some kind of error message here
if (error) { return <p>Error...</p> }
const { edges } = data.getHMCInquiryListing
if (!ref.current) {
// will only be called once
// some data transformation ...
setKeys(tmpKeys)
setValues(tmpValues)
ref.current = true;
}
return (
<QueryContext.Provider value={contextValue}>
<FilterSidebar keys={keys} values={values} />
<Canvas data={edges} />
</QueryContext.Provider>
)
}
export default App;
Child component:
import React, { memo } from "react"
import GenericFilter from './GenericFilter.js'
import SpecificFilter from './SpecificFilter.js'
const FilterSidebar = (props) => {
const {keys, values} = props
return (
<div className='filter-sidebar'>
<div className="filters">
<GenericFilter attributes={keys} />
{keys.map(attribute => {
return <SpecificFilter key={attribute} attribute={attribute} values={values[attribute]} />
})}
</div>
</div>
);
}
const areEqual = (prevProps, nextProps) => {
console.log(prevProps, nextProps)
}
export default memo(FilterSidebar, areEqual)
Thanks in advance.