Let's go through the following steps to implement the QuestionList component:
- Let's create a file called QuestionList.tsx and add the following import statements:
import { FC } from 'react';
/** @jsx jsx */
import { css, jsx } from '@emotion/core';
import { gray5, accent2 } from './Styles';
import { QuestionData } from './QuestionsData';
Notice that we have imported FC from React.
- Now, let's define the interface for the component props underneath the import statements:
interface Props {
data: QuestionData[];
}
We have called the props interface Props and it contains a single property to hold an array of questions.
- Let's start by implementing the QuestionList component:
export const QuestionList: FC<Props> = props => null;
We have defined props that can be passed into the component of the Props type. This means we can pass a data prop into QuestionList when we reference it in JSX.
- At the moment, we aren't rendering anything in the QuestionList component. We are going to render the questions in an unordered list:
export const QuestionList: FC<Props> = props => (
<ul
css={css`
list-style: none;
margin: 10px 0 0 0;
padding: 0px 20px;
background-color: #fff;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
border-top: 3px solid ${accent2};
box-shadow: 0 3px 5px 0 rgba(0, 0, 0, 0.16);
`}
>
</ul>
);
So, the unordered list will appear without the bullet points and with a rounded border. The top border will be slightly thicker and in the accent color. We've added a box shadow to make the list pop out a bit.
- Now, let's start to create the list items:
export const QuestionList: FC<Props> = props => (
<ul ...
>
<li
css={css`
border-top: 1px solid ${gray5};
:first-of-type {
border-top: none;
}
`}
>
</li>
</ul>
);
So, the list items will have a light gray line between them.
- Now, we can inject the data into the list:
export const QuestionList: FC<Props> = props => (
<ul ...
>
{props.data.map(question => (
<li
key={question.questionId}
css={...}
>
</li>
))}
</ul>
);
Note that we're referencing the data prop and calling a map function nested inside the List component. map iterates through the items in the array, calling the function passed to it for each item. So, we iterate through the questions that are passed into QuestionList and render a li HTML element for each array item.
Notice the key prop we pass into the li element.
- Our QuestionList component will work perfectly fine, but we are going to make one small change that will arguably make the implementation a little more succinct. The change is to destructure the props into a data variable in the function parameter:
export const QuestionList: FC<Props> = ({ data }) => (
<ul ... >
{data.map(question => (
<li ... >
</li>
))}
</ul>
);
Notice that we directly reference the data variable in the JSX and not through the props variable, like we did in the previous example. This is a nice pattern to use, particularly when there are more props.
Before we can complete the QuestionList component, we are going to create its child component, Question, which we'll do next.