waleedd32
waleedd32

Reputation: 533

converting componentDidMount, componentDidUpdate into hooks

New to react hook world, trying to learn by coding, i'm not sure about this componentDidUpdate to where put it inside useEffect any suggestions ? this is my code:

componentDidMount() {
  if (!this.props.realGraph) {
    this.loadGraph();
  }
  
  this.refs.graphDiv.addEventListener("click", this.onClickGraphDiv, true);
}

discardGraph() {
  this.props.clearGraphData();
  this.loadGraph();
}

componentDidUpdate() {
  this._zoomConfig();
}

_zoomConfig = () => {
  const z = d3Select(`#graph-id-graph-wrapper`)
  .call(d3Zoom())
  .on("dblclick.zoom", null)
  .on("mousedown.zoom", null)
};

realGrpah comes from mapStateToProps

this is what i have done converting it to hooks,

useEffect(() => {
  if (!props.realGraph) {
    loadGraph();
  }
  
  refs.graphDiv.addEventListener("click", onClickGraphDiv, true);
  _zoomConfig();
}, []);


discardGraph() {
  props.dispatch(clearGraphData())
  loadGraph();
}

_zoomConfig = () => {
  const z = d3Select(`#graph-id-graph-wrapper`)
  .call(d3Zoom())
  .on("dblclick.zoom", null)
  .on("mousedown.zoom", null)
};

Upvotes: 0

Views: 153

Answers (2)

Tushar Walzade
Tushar Walzade

Reputation: 3809

I'm also not a super expert in react, but following solution might be useful for your scenario -

For DidMount, the use case is very straightforward -

useEffect(() => {
    // your code
}, []); // passing an empty dependency array will fire it only for the first time when component renders

For achieving DidUpdate, You can pass a prop from your parent component to your current component & fire an effect on updation of that prop as follows -

for example, you've used this component in parent component as -

const [updateZoom, setUpdateZoom] = useState(0);    // using this to update child component

// handleZoom on some event
const handleZoom = () => {
    setUpdateZoom(uz => uz + 1);
}

return (
    <GraphComponent realGraph={realGraph} clearGraphData={clearGraphData} updateZoom={updateZoom} />
);

And use updateZoom in your current/ child component as follows -

useEffect(() => {
    console.log('updateZoom did update');
    this._zoomConfig();
}, [updateZoom]);

Upvotes: 0

Nick
Nick

Reputation: 16576

You can use a separate effect that fires on every re-render:

// Approximately component did mount
useEffect(() => {
  if (!props.realGraph) {
    loadGraph();
  }  
  refs.graphDiv.addEventListener("click", onClickGraphDiv, true);
}, []);

// Approximately component did update
useEffect(() => {
  _zoomConfig();
})

Now if you don't want it to fire on the first render, you can create a ref to a boolean that you use to ignore the initial mounting, which I believe would be more analogous to componentDidUpdate:

// Approximately component did mount
useEffect(() => {
  if (!props.realGraph) {
    loadGraph();
  }  
  refs.graphDiv.addEventListener("click", onClickGraphDiv, true);
  _zoomConfig();
}, []);

// Approximately component did update
const isMounted = useRef(false);
useEffect(() => {
  if (!isMounted.current) {
    isMounted.current = true;
  } else {
    _zoomConfig();
  }
})

Upvotes: 3

Related Questions