I am rending two simple joke cards in TypeScript and the cards do show up in my browser but I also get this error: 'Jokes' cannot be used as a JSX component. Its return type 'Element[]' is not a valid JSX element. Type 'Element[]' is missing the following properties from type 'ReactElement<any, any>': type, props, key
I am new to TypeScript and cannot figure out for the life of me what the problem is. I have tried adding <></>
between the <Jokes />
in my App.tsx file but that doesn't work. I can't figure it out and was hoping someone could guide me in fixing this.
Jokes.tsx
import { jokeList, JokesPunchlines } from './jokeList';
import './App.css';
function Jokes() {
return (
jokeList.map((joking: JokesPunchlines) => {
return (
<div className="box">
<strong>{joking.setup}</strong>
<br />
<p>{joking.punchline}</p>
</div>
);
})
);
}
export default Jokes;
Joke List
export interface JokesPunchlines {
id: number,
setup: string,
punchline: string,
}
export const jokeList: JokesPunchlines[] = [
{
id: 1,
setup: "What's the best thing about a Boolean?",
punchline: "Even if you're wrong, you're only off by a bit"
},
{
id: 2,
setup: "Why do programmers wear glasses?",
punchline: "Because they need to C#"
}
];
App.tsx
import './App.css';
import Jokes from './Jokes';
function App() {
return (
<Jokes />
);
}
export default App;
index.tsx
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);
I have tried adding <></>
between the <Jokes />
in my App.tsx
file but that doesn't work. I can't figure it out and was hoping someone could guide me in fixing this.
CodePudding user response:
Just as the error says, an array of React components isn't a React component itself. While it'll still work in the JavaScript, TypeScript doesn't like it. You can rectify it by adding a JSX fragment around the returned array, and interpolate the array into the fragment. You can also leave off the : JokesPunchlines
since jokeList
is typed properly (and maybe call the mapping argument, a joke object, joke
or jokeObj
or something - joking
isn't a great variable name).
function Jokes() {
return (
<>
{
jokeList.map((joke) => {
return (
<div className="box">
<strong>{joke.setup}</strong>
<br />
<p>{joke.punchline}</p>
</div>
);
})
}
</>
);
}
CodePudding user response:
By using implicite return typescript has some difficultie.
You can type function Jokes with return type. Its will help.
also this should do the job.
import { jokeList, JokesPunchlines } from './jokeList';
import './App.css';
function Jokes() {
return <>{
jokeList.map((joking: JokesPunchlines) => {
return (
<div className="box">
<strong>{joking.setup}</strong>
<br />
<p>{joking.punchline}</p>
</div>
);
})
}</>;
}
export default Jokes;