imperative logic on component that renders non-React components (mostly)

Marcus Junius Brutus

I have a React component (let's call it A) that mainly renders a non-React component (a GIS map) and will on certain occasions display some modal dialogs. These dialogs are the only proper React components that the A component renders and are controlled by A's local State. The GIS map draws some features (polygons) which the component receives through its props, but the logic to draw these features is purely imperative as the GIS map cannot be controlled by React.

So I have the following approach:

componentDidUpdate(prevProps, prevState) {
    // check for changes between prevProps and this.props and
    // imperatively draw new polygons on map or remove polygons etc.
}

This works. However it occurred to me that when a new polygon arrives via props, the render is not necessary. This is because drawing the polygons on the map is done in an imperative way via direct DOM manipulation (through API calls to the GIS library). As such, I wrote a shouldComponentUpdate as follows:

shouldComponentUpdate(nextProps, nextState) {
   return !isEqual(nextState, this.state); // isEqual from lodash doing a deep comparison
}

The idea is that I only re-render my component for local state changes (which control a couple of modal dialogs) since these are the only React-controlled parts of the component and require render to be called. The rest of the changes (that affect non-React components) I pick up in componentDidUpdate and enforce imperatively (that was the plan at least).

The problem with the new approach is that if shouldComponentUpdate returns false, then componentDidUpdate is not called at all. So the only way to get hold of props changes that trigger imperative logic is via componentWillReceiveProps which is however deprecated.

Any thoughts? Is my approach flawed in a deeper level and/or how to deal with this connundrum? Is what I am trying to accomplish achievable only using a functional component approach (as has been suggested by a comment) and can I achieve it with class components as well?

Martin

Seems to be an interesting problem. How are props mapped to your GIS-Widget? React does allow nested elements that are not under react rule (docu).

I would ditch the old class based lifecycle functions and implement a functional component with useEffect and useRef hook.

Does the following code somehow resemble your current issue? Let me know what I got wrong and we can make it work.

import React, { useRef, useEffect, useState } from 'react';
import gismap from 'gis-map';

const MyGISWrapper = ({ streets, waterways }) => {
  const map = useRef();

  // only once, on first render
  useEffect( () => { if (map.current) gismap('init', map.current); }, []);

  // update polygons when props change
  useEffect( () => {
    if (map.current) map.current.gismap('update', streets, waterways);
  }, [streets, waterways]);

  // some example modal
  const [showConfirmation, setShowConfirmation] = useState(false);
  const openConfirmation = () => setShowConfirmation(true);
  const closeConfirmation = () => setShowConfirmation(false);

  return (
    <div className="container">
      <div className="gis-map-root" ref={map} />
      <div className="modal-popup-area">
        { showConfirmation && <Confirmation onClose={closeConfirmation} /> }
      </div>
      <button onClick={openConfirmation} />
    </div>
  );
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

imperative logic on component that renders non-React components (mostly)

From Dev

How to share component logic with other components in a clean way on react native?

From Dev

Similar React components with different logic

From Dev

React, adding components in component

From Dev

React JS component renders multiple times in Meteor

From Dev

React setState renders component twice when called

From Dev

how react-native renders the TouchableOpacity components on the same row - horizontally

From Java

React: Firebase auth function calls by itself when the component renders

From Dev

How to detect child renders in a parent component in react.js

From Dev

Bizarre problem with React component which renders wrong HTML code

From Dev

Using position: 'Absolute' and display: 'None' in React Native still renders the component

From Dev

React re-renders whole app after rendering a component

From Dev

Dynamically insert react components into another react component

From Dev

React Component that recursively loads other components

From Dev

Components overriding eachother/Component organization in React

From Dev

How to split react component into nested components

From Dev

How can I render a component in DOM body even if some other component renders it in react?

From Dev

React - does a child component re-mount each time the parent component renders?

From Dev

Footer renders between navbar and component instead of after the component in React-Redux

From Dev

Component re-renders when using react-navigation for react native

From Dev

eslint rule to require React components to extend React.Component?

From Java

Difference between declarative and imperative in React.js?

From Dev

Not able to access store on non react component

From Dev

Interacting with React components from non-react world

From Java

Why React renders a component even though I don't pass anything to it?

From Dev

Should I use a React Component if it always renders null, or just use a function?

From Dev

React Hooks: component re-renders one step behind on state update

From Dev

I'm not understandng why React.memo is needed on this Speaker Component to keep from extra renders

From Dev

React component renders data from Flux store but not when fetched from Mongo database

Related Related

  1. 1

    imperative logic on component that renders non-React components (mostly)

  2. 2

    How to share component logic with other components in a clean way on react native?

  3. 3

    Similar React components with different logic

  4. 4

    React, adding components in component

  5. 5

    React JS component renders multiple times in Meteor

  6. 6

    React setState renders component twice when called

  7. 7

    how react-native renders the TouchableOpacity components on the same row - horizontally

  8. 8

    React: Firebase auth function calls by itself when the component renders

  9. 9

    How to detect child renders in a parent component in react.js

  10. 10

    Bizarre problem with React component which renders wrong HTML code

  11. 11

    Using position: 'Absolute' and display: 'None' in React Native still renders the component

  12. 12

    React re-renders whole app after rendering a component

  13. 13

    Dynamically insert react components into another react component

  14. 14

    React Component that recursively loads other components

  15. 15

    Components overriding eachother/Component organization in React

  16. 16

    How to split react component into nested components

  17. 17

    How can I render a component in DOM body even if some other component renders it in react?

  18. 18

    React - does a child component re-mount each time the parent component renders?

  19. 19

    Footer renders between navbar and component instead of after the component in React-Redux

  20. 20

    Component re-renders when using react-navigation for react native

  21. 21

    eslint rule to require React components to extend React.Component?

  22. 22

    Difference between declarative and imperative in React.js?

  23. 23

    Not able to access store on non react component

  24. 24

    Interacting with React components from non-react world

  25. 25

    Why React renders a component even though I don't pass anything to it?

  26. 26

    Should I use a React Component if it always renders null, or just use a function?

  27. 27

    React Hooks: component re-renders one step behind on state update

  28. 28

    I'm not understandng why React.memo is needed on this Speaker Component to keep from extra renders

  29. 29

    React component renders data from Flux store but not when fetched from Mongo database

HotTag

Archive