Skip to content
tezvyn:

Write the React.createElement() equivalent for this JSX

Source: react.devHardHow cards are made

Write the React.createElement() equivalent for this JSX

Tests JSX-to-JS compilation mechanics. Answer: createElement('a', {href: '/home', className: 'link'}, 'Go Home'). Children must be the third argument, not inside props. Red flag: nesting children in props or using an unquoted tag variable.

What's really being asked

This question evaluates whether you understand JSX as a compile-time syntax transform rather than runtime HTML. Interviewers want to see that you know exactly how Babel or a similar compiler rewrites angle-bracket code into plain JavaScript function calls. At the senior level, they are checking for precision in the argument order, the distinction between props and children, and awareness of how React distinguishes host components from custom components via capitalization.

The full answer

First, the exact call signature: createElement('a', {href: '/home', className: 'link'}, 'Go Home'). The tag name is a lowercase string because it is a built-in HTML element. Second, the props object contains every attribute from the JSX tag as a key-value pair, preserving the exact names used in JSX, so className stays className. Third, text content between opening and closing tags becomes the third argument, not a property inside the props object. Fourth, if there were multiple children, they would be passed as additional arguments or as an array in the third position, but never as props.children when using the createElement API directly in this form.

The mistakes people make

Nesting children inside props, such as {href: '/home', className: 'link', children: 'Go Home'}, shows a misunderstanding of the transform; while element.props.children exists on the resulting element object, the createElement API separates children from the props argument. Passing an unquoted a as the first argument implies you think JSX leaves lowercase tags as variables, which is incorrect; it compiles them to quoted strings. Swapping the second and third arguments or omitting the props object entirely are also immediate red flags. Some candidates incorrectly change className to class, revealing confusion about where DOM property normalization happens.

What usually comes next

How would this change if the tag were a custom component like <Link href="/home">? The answer is createElement(Link, {href: '/home'}, 'Go Home') with an unquoted identifier. What happens to the key and ref props? They are extracted from the props object and attached directly to the returned element object, so they do not appear on element.props. How would you handle a dynamic list of children? Pass the array as the single third argument rather than spreading with unknown length, because createElement('ul', {}, items) is preferred over createElement('ul', {}, ...items) when items is dynamic.

A concrete example

If the JSX were <ul className="list"><li>One</li><li>Two</li></ul>, the equivalent would be createElement('ul', {className: 'list'}, createElement('li', null, 'One'), createElement('li', null, 'Two')). Notice that null is supplied when there are no props, and each nested element is itself a createElement call. This nesting is exactly what the JSX compiler produces under the hood.

Interview question

Which call reflects how Babel transforms the JSX <a href='/home' className='link'>Go Home</a> into React.createElement()?

  • a.React.createElement('a', {href: '/home', className: 'link', children: 'Go Home'})
  • b.React.createElement('a', {href: '/home', className: 'link'}, 'Go Home')Correct
  • c.React.createElement(a, {href: '/home', className: 'link'}, 'Go Home')
  • d.React.createElement('a', {href: '/home', class: 'link'}, 'Go Home')
Why?

The JSX transform emits a quoted string for lowercase host tags, places attributes in the second argument preserving className, and passes text children as the third argument, not inside props. Option A is tempting because the resulting element object has props.children, but the createElement API signature requires children as a separate argument from props.

Just read this? Test yourself on what you have been reading.

Read the original → react.dev

You just looked this up. Could you explain it out loud?

That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Open roles that interview on react — each one lists the topics its interview covers.

See open roles