The type 'Item' cannot be assigned to type 'ReactNode'

I'm having trouble understanding the meaning of this error. I've created a Type for an array of items where each item is a string.

Interestingly, when I enclose the listItem within an empty fragment, the error disappears. Is there something I'm overlooking? Each item should be a string only within an array of items.

export type Item = {
  listItem: string;
};

 

import { motion } from 'framer-motion';

import { Item } from '@typings/propTypes';

import { container, item } from '@lib/framer';

const UnorderedList = ({
  listItems,
  htmlClass
}: {
  htmlClass: string;
  listItems: Item[];
}) => (
  <motion.ul
    variants={container}
    initial="hidden"
    animate="show"
    className={`flex flex-col flex-wrap my-6 leading-relaxed ${
      htmlClass ? htmlClass : 'text-white'
    }`}
  >
    {listItems.map((listItem, index) => (
      <motion.li key={index} variants={item} className="flex gap-3">
        {listItem}
      </motion.li>
    ))}
  </motion.ul>
);

export default UnorderedList;

Answer №1

listItem refers to an object of the Item type, containing a property named listItem which is a string. React does not allow objects as child elements, hence using {listItem} is incorrect. TypeScript catches this error during authoring/compilation before React does so at runtime. Consider using {listItem.listItem}, as strings are acceptable React children.

Here is a simplified example demonstrating the issue:

import React from "react";

export type Item = {
    listItem: string;
};

// Incorrect implementation
const Example1 = ({item}: {item: Item}) => {
    return <div>{item}></div>;
};

// Correct implementation
const Example2 = ({item}: {item: Item}) => {
    return <div>{item.listItem}</div>;
};

Playground link

Wrapping the listItem with an empty fragment resolves the error.

Unfortunately, this action merely masks the issue from TypeScript. The underlying problem persists, and React will display an error:

// Stack Snippets don't support shorthand fragment syntax,
// so we have to use the verbose form here
const Example1 = ({item}: {item: Item}) => {
    return <div><React.Fragment>{item}</React.Fragment></div>;
};

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Example1 item={{listItem: "Hi"}} />);
<div id="root"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>

This will trigger the common runtime error: "Objects are not valid as a React child".

Error: Objects are not valid as a React child (found: object with keys {listItem}).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Implement the usage of plainToClass within the constructor function

I have a dilemma with my constructor that assigns properties to the instance: class BaseModel { constructor (args = {}) { for (let key in args) { this[key] = args[key] } } } class User extends BaseModel { name: str ...

Enhance Material UI with custom properties

Is it possible to add custom props to a Material UI component? I am looking to include additional props beyond what is provided by the API for a specific component. For example, when using Link: https://material-ui.com/api/link/ According to the document ...

Exploring the versatility of Vue.js through props and scoped slots

Coming from a React background, I am used to being able to easily alter children components before they render. However, after spending hours reading the VueJS documentation and searching forums, I have not been able to find a straightforward way to do thi ...

Retrieving data from an API using VUEJS3 and Typescript

I am facing an issue with displaying data in my template. When I try to do so, the screen remains blank. I am using Vue.js 3 with TypeScript and I am fairly new to this technology. <template> <div> <img :src="datas[0].imag ...

RxJs Subject: Acquiring the Sender

I have been working with Subjects and there is a .subscribe() in a specific class. Emitting values to this class from different other classes has resulted in the subscribe function being triggered multiple times, yet I am unsure of where these emits are co ...

Tips for defining a distinct series of key-value pairs in typescript

Having experience with a different language where this was simple, I am finding it challenging to articulate a sequence of pairs: Each pair is made up of two basic elements (such as strings or numbers) Each element may appear multiple times within the lis ...

Unlocking new perspectives with a click

Currently exploring Angular development, I have encountered a question here but couldn't find the solution I was looking for. I am seeking suggestions and ideas on how to approach this issue. Essentially, my HTML includes buttons like the ones shown ...

Apply a CSS class when the tab key is pressed by the user

Currently in my Angular 14 project, I am working on a feature where I need to apply "display: block" to an element once the user reaches it using the tab key. However, I am struggling with removing the "display: block" when the user tabs out of the element ...

Using Angular to Bind Checkbox Value in Typescript

I have a challenge of creating a quiz where a card is displayed with 4 questions structured like this: <div class="col-md-6"> <div class="option" id="Answer1"> <label class="Answer1"> <input value= "Answer1" type="checkbox ...

Ways to define a static variable within a function using Typescript

There is a common approach to declaring a Static Variable or Function within a Class, demonstrated here: class SomeClass(){ static foo = 1; static fooBar(){ return ++SomeClass.foo; } } However, is it possible to declare a Static Local Variable ...

Error in TypeScript in VSCode when using the React.forwardRef function in a functional component

We are developing our component library using JavaScript instead of TypeScript. In our project's jsconfig.json file, we have set checkJs: true. All components in our library are functional and not based on class components. Whenever a component needs ...

What could be the reason for the inconsistent behavior of onClick, causing it to occasionally fail to display the associated

I just started using typescript 2 days ago, mainly to create a custom component for my streamlit app. I've made a navigation bar with a tab that can be clicked on the sidebar, but it's displaying some erratic behavior. Sometimes when I click on t ...

npm encountered an issue when attempting to install a package from a local directory: EISDIR: illegal operation on a directory, read

While attempting to add my compiled TypeScript output as a local package using npm, this error appears: $ npm install --save ../app/out npm ERR! eisdir EISDIR: illegal operation on a directory, read npm ERR! eisdir This is most likely not a problem wit ...

The 'items' property cannot be linked to 'virtual-scroller' as it is not a recognized attribute

I'm currently facing an issue with integrating virtual scroll into my Ionic 4 + Angular project. Previously, I relied on Ionic's implementation of virtual scroll (ion-virtual-scroll) which worked well initially. However, I encountered a major dr ...

What could be causing the error in Angular 2 when using multiple conditions with ng-if?

My aim is to validate if the length of events is 0 and the length of the term is greater than 2 using the code below: <li class="more-result" *ngIf="events?.length == 0 && term.value.length > 2"> <span class="tab-content- ...

Leverage Component class variables within the Component hosting environment

Is there a way to utilize a class variable within the @Component declaration? Here is the method I am aiming for: @Component({ selector: "whatever", host: { "[class]":"className" } }) export class MyComponent { @Input() className: ...

Leverage the generic types of an extended interface to simplify the creation of a shorthand type

Attempting to streamline my action shorthand that interacts with AsyncActionCreators. A function has been crafted to accept a React dispatch: Dispatch<T> parameter: const fetchProfileAction = actionCreator.async<void, Profile, any>('FETC ...

Steps to access a Request object within a Controller

I am currently working with Express and Typescript, utilizing Controllers for managing requests. In an attempt to create a BaseController that includes the Request and Response objects for each request, I wrote the following code snippet. However, it see ...

Troubleshooting: Issue with Button Layout in Ionic's ItemSliding Component

How can I create a list item that allows swiping to reveal an archive button? The requirement is for the icon to appear to the left of the text. I'm referring to the documentation on Button Layout: https://ionicframework.com/docs/api/components/item ...

How come TypeScript tuples support the array.push method?

In the TypeScript code snippet below, I have specified the role to be of Tuple type, meaning only 2 values of a specified type should be allowed in the role array. Despite this, I am still able to push a new item into the array. Why is the TS compiler not ...