34

Im trying to convert one of my components to a functional stateless component (FSC).

But FSC will not be optimized if using ...rest, therefore i need to destruct the components props.

I call Link as

<Link to={link} data-navbar-click="close-menu">{name}</Link>

then in Link i want to destruct the hyphen cased> data-navbar-click prop:

function Link({ to, className, onClick, target, rel, key, data-navbar-click}) {

However that doesnt compile. So i tried:

function Link({ to, className, onClick, target, rel, key, ['data-navbar-click']}) {

But that doesnt work as well.

user3711421
  • 1,658
  • 3
  • 20
  • 37

2 Answers2

51

Simplest solution: use alias.

const Link = ({
  to,
  className,
  onClick,
  target,
  rel,
  key,
  'data-navbar-click': dataNavbarClick,
}) => {
  const test = dataNavbarClick;
};

dataNavbarClick should have the value "close-menu"

horymury
  • 536
  • 6
  • 8
2

You can write a utility function that transforms camelCase key names to kebab/hyphen-case properties, picked them out out of the props object and, by using JSX spread, render them in the component.

Example below:

import kebabCase from 'lodash/kebabCase';

const props = {
  dataNavAttr: 'close-menu',
  itemCount: 100
}

const pickAndTransformDataProps = (props, findByKey) => {
  const pickedProps = {};
  Object.keys(props).map(key => {
    if (key.includes(findByKey)){
      pickedProps[kebabCase(key)] = props[key];
    }
  });
  return pickedProps;
}

const pickedDataProps = pickAndTransformDataProps(props, 'data');
console.log({ pickedDataProps }); 
// Using JSX spread: <Component onClick={props.onClick} { ...pickedDataProps } />
Denialos
  • 956
  • 7
  • 16
  • 2
    I would have liked it without using an external lib. I noticed i could just do: function `Link(props) {const dataNavbarClick = props['data-navbar-click'];` then do my regular `const { to, className, onClick, target, rel, key} = props}`.. Strange though that i couldnt destruct it – user3711421 Aug 09 '17 at 14:27
  • 1
    Well, how about passing in an extra object to props which will contain data attrbute props only? Like `const dataAttrProps = { 'data-link: 'smth', 'etc': 'etc' };` and then simply spread that `dataAttrProps ` in JSX like `{ ...props.dataAttrProps }`. This seems like the cleanest approach to me. – Denialos Aug 09 '17 at 14:54