4

So I want to create a react component in typescript, imagelist, that displays a list of images, links and numbers.

My json looks something like this

{   "_id": "59c8ead6411f1e56f498a71b",   "images": [
    {
      "post_url": "http://www.Facebook.com/974",
      "image_url": "http://placehold.it/32x32",
      "count": 887
    },
    {
      "post_url": "http://www.Facebook.com/711",
      "image_url": "http://placehold.it/32x32",
      "count": 749
    }   ] }

I have a dashboard component that looks like this

import * as React from 'react'; 
const fakeData = require('./fake_data.json'); 
import ImageList from './ImageList';

export default class Dashboard extends React.Component {   render() {
    return (
      <div>
        <ImageList data={fakeData.images} />
      </div>
    );   } }

I have tried to define my imagelist component as follows

import * as React from 'react';

interface ImageListValue {
  post_url: string;
  image_url: string;
  count: number;
}

interface ImageListProps {
  data: ImageListValue[];
}

const ImageList = ({ data }: ImageListProps) => {
  return data.map(item => {
    return (
      <div key={item.post_url}>
        <a href={item.post_url}>{item.post_url}</a>
        <img src={item.image_url} />
        <h1>item.count</h1>
      </div>
    );
  });
};

export default ImageList;

There linter shows no problems in the ImageList component, but in the Dashboard component I get the following message.

JSX element type 'Element[]' is not a constructor function for JSX elements.
  Property 'render' is missing in type 'Element[]'.
[ts] JSX element class does not support attributes because it does not have a 'props' property.

I'm not sure what this error message means. My first thought was that I needed to use a SFC type definition as described [here][1] [1]: https://medium.com/@iktakahiro/react-stateless-functional-component-with-typescript-ce5043466011 .

I changed my code to this

const ImageList: React.SFC<ImageListProps> = ({data}) => {
  return data.map(item => {
    return (
      <div key={item.post_url}>
        <a href={item.post_url}>{item.post_url}</a>
        <img src={item.image_url} />
        <h1>item.count</h1>
      </div>
    );
  });
};

and received another error

[ts]
Type '({ data }: ImageListProps & { children?: ReactNode; }) => Element[]' is not assignable to type 'StatelessComponent<ImageListProps>'.
  Type 'Element[]' is not assignable to type 'ReactElement<any> | null'.
    Type 'Element[]' is not assignable to type 'ReactElement<any>'.
      Property 'type' is missing in type 'Element[]'.
const ImageList: React.StatelessComponent<ImageListProps>

I'm new to typescript and feel like I am missing some key things. Any ideas?

1
  • I believe this error is caused by the data type you're using for ImageList Commented Sep 25, 2017 at 14:59

1 Answer 1

9

The error is a bit obscure, but the problem is that your function returns an array of ReactElement's instead of just one (returning an array will be allowed in react 16). If you wrap it in a parent div it should work:

const ImageList : React.SFC<ImageListProps> = ({data}) => (
  <div>
    { data.map(item => (
        <div key={item.post_url}>
          <a href={item.post_url}>{item.post_url}</a>
          <img src={item.image_url} />
          <h1>item.count</h1>
        </div>
    ))}
  </div>
);

(also removed a couple of redundant return statements)

Sign up to request clarification or add additional context in comments.

3 Comments

Can you please provide reference link for Two way binding in ReactJs Stateless Functional Component
There's no two-way binding here, so I'm not sure what link you're referring to.
Thank you so much. I've been trying to decipher this for way too long.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.