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 THIS TESTS: 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.
A GOOD ANSWER COVERS: 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.
COMMON WRONG ANSWERS: 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.
LIKELY FOLLOW-UPS: 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.
ONE 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.
Source: react.dev
Read the original → react.dev
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.