Hide Element Dynamically in ReactJS

windupurnomo :

I have concern about managing access right in web side. A user with Admin Role can see everything in web. A user with Finance Role just can see some of elements. I manage this condition in database like these.

  • Admin can access: everything
  • Finance can access elements: A, B
  • Warehouse can access elements: A, C
<div id="a">
  Component A
</div>
<div id="b">
  Component B
</div>
<div id="c">
  Component C
</div>

I can do manually by doing this:

export default props => {
  const allowedElements = ['a', 'b']; // get by role of current user
  return (
    <>
      {allowedElements.indexOf('a') >= 0 && <div>Component A</div>}
      {allowedElements.indexOf('b') >= 0 && <div>Component B</div>}
      {allowedElements.indexOf('c') >= 0 && <div>Component C</div>}
    </>
  );
}

I hope there is effective / simple ways to handle this condition. Can you give suggestion to me?

Additional The solution I hope can handle nested element. In below code, element B and C one of them can hide based on role.

<div id="a">
  Component A
</div>
<div>
  <div id="b">
    Component B
  </div>
  <div id="c">
    Component C
  </div>
</div>

windupurnomo :

After few times to googling, I get React.Children. By using this, I can modify 'everything'.

  • Loop through our elements and it's children using React.Children.map
  • On every elements and child, check if ID is authorize to access, show it
  • element who have not ID just return as is.

Code Sandbox: https://codesandbox.io/s/heuristic-wilbur-kk3r1

Before element really returned, I will evaluate it's show/or hide

  const b = React.Children.map(myComponent, (child, i) => {
    return check(child);
  });

It's logic to iterate through elements and child

  const check = child => {
    const p = child.props;
    if (p.id && allowedElements.indexOf(p.id) < 0) return null;
    else if (Array.isArray(p.children)) return p.children.map(c => check(c));
    else if (typeof p.children === "object") return check(p.children);
    else return child;
  };

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=342356&siteId=1