Programmatically Set Data Attribute in React with TypeScript

I wanted to programmatically set the data attribute of a specific component, so that it could be easily identified in testing. The question was how to programmatically set props of a React component in TypeScript.

Data Attribute

HTML has a nice data attribute, which can be useful for storing extra data. Setting the data attribute with key city:

return (
<Box data-city="London">
<p>Hello</p>
</Box>
);

The value of the citydata could be obtained from the dataset object:

const box = document.querySelector({/* some selector */});
box.dataset.city // "London"

I wanted to avoid hard-coding the key and the value, and instead get them through props.

Programmatically Setting Props

I defined variables for getting the data attribute key and value, namely dataAttrName and dataAttrValue .

interface ComponentProps {
dataAttrName: string;
dataAttrValue: string;
};

Appending the dataAttrName to string literal data- produces the required key, which is then used to insert the dataAttrValue into the props object for the component. The resulting props object can be destructured directly inside the JSX element.

For example, if I wanted to dynamically set data attribute of an MUI Box component, I could do the following:

const Component: FC<ComponentProps> = ({ dataAttrName, dataAttrValue
}) => {
  let props = {} as BoxProps;
const key = `data-${dataAttrName}`;
const dataAttrKey = key as keyof BoxProps;
props[dataAttrKey] = dataAttrValue;
  return (
<Box {...props}>
<p>Hello</p>
</Box>
);
};
export default Component;

Using this component:

export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<Component dataAttrName="city" dataAttrValue="London" />
<Component dataAttrName="country" dataAttrValue="England" />
</div>
);
};

Inspecting the elements shows that they contain the correct data :

Note on Type Safety

Technically, with this approach, it is possible to set any prop at all, but this could easily lead to funky behaviour. For example, I can pass a function reference as a child of a component (which is wrong):

let props = {} as BoxProps;
const key = `children`;
const dataAttrKey = key as keyof BoxProps;
props[dataAttrKey] = () => {};
return (
<Box style={{ backgroundColor: "#fabcea", width: 100, height: 100 }} {...props} ></Box>
);

It compiles, but React warns us that functions aren’t valid children of React components:

By casting key variable, I am stating here that I am sure that this keyis in the keyset of BoxProps, which is why it’s not safe:

const dataAttrKey = key as keyof BoxProps;

I think this approach could be suitable for setting data attributes. Prefixing the key with ‘data-‘ ensures that it is only setting data attributes, and if something along the line doesn’t work, the functionality of the component is unaffected.

However, I think this is potentially troublesome for anything else.

Conclusion

This is one way to programmatically set data attributes in TypeScript for React components.

This may be useful for testing, when id and name tags aren’t suitable. This is what I used it for, we needed a better way of identifying components for testing with Selenium, and this was one solution that emerged.


Programmatically Set Data Attribute in React with TypeScript was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Level Up Coding - Medium and was authored by Fedor Selenskiy

I wanted to programmatically set the data attribute of a specific component, so that it could be easily identified in testing. The question was how to programmatically set props of a React component in TypeScript.

Data Attribute

HTML has a nice data attribute, which can be useful for storing extra data. Setting the data attribute with key city:

return (
<Box data-city="London">
<p>Hello</p>
</Box>
);

The value of the citydata could be obtained from the dataset object:

const box = document.querySelector({/* some selector */});
box.dataset.city // "London"

I wanted to avoid hard-coding the key and the value, and instead get them through props.

Programmatically Setting Props

I defined variables for getting the data attribute key and value, namely dataAttrName and dataAttrValue .

interface ComponentProps {
dataAttrName: string;
dataAttrValue: string;
};

Appending the dataAttrName to string literal data- produces the required key, which is then used to insert the dataAttrValue into the props object for the component. The resulting props object can be destructured directly inside the JSX element.

For example, if I wanted to dynamically set data attribute of an MUI Box component, I could do the following:

const Component: FC<ComponentProps> = ({ dataAttrName, dataAttrValue
}) => {
  let props = {} as BoxProps;
const key = `data-${dataAttrName}`;
const dataAttrKey = key as keyof BoxProps;
props[dataAttrKey] = dataAttrValue;
  return (
<Box {...props}>
<p>Hello</p>
</Box>
);
};
export default Component;

Using this component:

export default function App() {
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<Component dataAttrName="city" dataAttrValue="London" />
<Component dataAttrName="country" dataAttrValue="England" />
</div>
);
};

Inspecting the elements shows that they contain the correct data :

Note on Type Safety

Technically, with this approach, it is possible to set any prop at all, but this could easily lead to funky behaviour. For example, I can pass a function reference as a child of a component (which is wrong):

let props = {} as BoxProps;
const key = `children`;
const dataAttrKey = key as keyof BoxProps;
props[dataAttrKey] = () => {};
return (
<Box style={{ backgroundColor: "#fabcea", width: 100, height: 100 }} {...props} ></Box>
);

It compiles, but React warns us that functions aren’t valid children of React components:

By casting key variable, I am stating here that I am sure that this keyis in the keyset of BoxProps, which is why it’s not safe:

const dataAttrKey = key as keyof BoxProps;

I think this approach could be suitable for setting data attributes. Prefixing the key with 'data-' ensures that it is only setting data attributes, and if something along the line doesn’t work, the functionality of the component is unaffected.

However, I think this is potentially troublesome for anything else.

Conclusion

This is one way to programmatically set data attributes in TypeScript for React components.

This may be useful for testing, when id and name tags aren’t suitable. This is what I used it for, we needed a better way of identifying components for testing with Selenium, and this was one solution that emerged.


Programmatically Set Data Attribute in React with TypeScript was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Level Up Coding - Medium and was authored by Fedor Selenskiy


Print Share Comment Cite Upload Translate Updates
APA

Fedor Selenskiy | Sciencx (2022-05-01T15:59:29+00:00) Programmatically Set Data Attribute in React with TypeScript. Retrieved from https://www.scien.cx/2022/05/01/programmatically-set-data-attribute-in-react-with-typescript/

MLA
" » Programmatically Set Data Attribute in React with TypeScript." Fedor Selenskiy | Sciencx - Sunday May 1, 2022, https://www.scien.cx/2022/05/01/programmatically-set-data-attribute-in-react-with-typescript/
HARVARD
Fedor Selenskiy | Sciencx Sunday May 1, 2022 » Programmatically Set Data Attribute in React with TypeScript., viewed ,<https://www.scien.cx/2022/05/01/programmatically-set-data-attribute-in-react-with-typescript/>
VANCOUVER
Fedor Selenskiy | Sciencx - » Programmatically Set Data Attribute in React with TypeScript. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2022/05/01/programmatically-set-data-attribute-in-react-with-typescript/
CHICAGO
" » Programmatically Set Data Attribute in React with TypeScript." Fedor Selenskiy | Sciencx - Accessed . https://www.scien.cx/2022/05/01/programmatically-set-data-attribute-in-react-with-typescript/
IEEE
" » Programmatically Set Data Attribute in React with TypeScript." Fedor Selenskiy | Sciencx [Online]. Available: https://www.scien.cx/2022/05/01/programmatically-set-data-attribute-in-react-with-typescript/. [Accessed: ]
rf:citation
» Programmatically Set Data Attribute in React with TypeScript | Fedor Selenskiy | Sciencx | https://www.scien.cx/2022/05/01/programmatically-set-data-attribute-in-react-with-typescript/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.