Function props

Props can consist of primitive types such as the boolean showContent prop we implemented in the Question component. Props can also be objects and arrays as we have experienced in the Question and QuestionList components. This in itself is powerful. However, props can also be functions, which allows us to implement components that are extremely flexible.

Using the following steps, we are going to implement a function prop on the QuestionList component that allows the consumer to render the question as an alternative to QuestionList rendering it:

  1. In QuestionList.tsx, add a renderItem function prop to the Props interface, as follows:
interface Props {
data: QuestionData[];
renderItem?: (item: QuestionData) => JSX.Element;
}

So, the renderItem prop is a function that takes in a parameter containing the question and returns a JSX element. Notice that we have made this an optional prop so that our app will continue to run just as it was before.

  1. Let's destructure the function parameters into a renderItem variable:
export const QuestionList: FC<Props> = ({ data, renderItem }) => ( ... )
  1. Now, we can call the renderItem function prop in the JSX if it has been passed and, if not, render the Question component:
{data.map(question => (
<li ... >
{renderItem ? renderItem(question) : <Question data={question} />}
</li>
))}

Notice that we use renderItem in the ternary condition, even though it isn't a boolean.

Conditions in if statements and ternaries will execute the second operand if the condition evaluates to truthy, and the third operand if the condition evaluates to falsy. true is only one of many truthy values. In fact, false, 0, "", null, undefined, and NaN are falsy values and everything else is truthy.

So, renderItem will be truthy and will execute if it has been passed as a prop.

  1. Our app will render the unanswered questions, just like it did before, by rendering the Question component. Let's try our renderItem prop out by opening HomePage.tsx and adding the Question interface to the import statement from Data
import { getUnansweredQuestions, QuestionData } from './QuestionsData';
  1. Next, let's create a function to render the question just above the HomePage component:
const renderQuestion = (question: QuestionData) => 
<div>{question.title}</div>;
  1. Now, we can pass this function into the renderItem prop on QuestionList in the HomePage JSX:
<QuestionList 
data={getUnansweredQuestions()}
renderItem={renderQuestion}
/>

If we look at the running app, we'll see this in effect:

The pattern of implementing a function prop to allow consumers to render an internal piece of the component is often referred to as a render prop. It makes the component extremely flexible and useable in many different scenarios.
  1. This doesn't look quite a good as it did previously, so we won't pass the renderItem prop. Let's have QuestionList take back control of rendering the questions:
<QuestionList data={getUnansweredQuestions()} />
  1. To complete this section, let's remove the renderQuestion function from HomePage.tsx, as well as the imported QuestionData interface, now that we aren't using them anymore.

We can already see that function props are extremely powerful. We'll use these again when we cover handling events later in this chapter. Before we look at events, we are going to cover another fundamental part of a component, which is state.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.222.144.244