代写 react Adding a Search Bar

Adding a Search Bar
In this worksheet, we will build on the work we have done with the earlier sheet on React and forms and update our Headline app to provide a basic search facility. The first thing to do is open up your existing app, in most cases from CodeSandbox. Currently, mine looks like this:
To start with, let’s add a search bar. There is an input type=”search” that we can use – how handy is that? As before, we will create a new component to handle the new functionality – that way we can use it again later if we want to. We will call the new component SearchBar. Inside, we will return a new div that has a label to tell people what the input is for, an input so that people can enter their search terms, and a button to submit the search. Note: because we’re not using a form, you should set the type of the button be a button – that way, the page won’t actually try and submit anything.
Now, because our button and our label probably say very similar things, we can use a different approach and not have the label at all. We need to add an id to the button, calling it something like search-button.
Next, we are going to consider accessibility. We will add a new prop to our input which we will call aria-labelledby. The value here will be the id of the button. To explain, aria is a set of attributes that help make applications accessible – ARIA is an acronym for ‘Accessible Rich Internet Applications’. So, we’re telling anything that is interested (usually a screen reader for vision-impaired users) that “If you want to find the label for this input, take a look at the item with this ID”. So, when a screen reader is looking over the page, it will see the input, and tell the user that it’s called ‘Search’ in our case. You can read more about labelling for accessibility here.
1

After these updates, your SearchBar should look like this:
function SearchBar() { return (


);
}
It isn’t terribly functional at the moment, but if we want to see how things might look, we can add it to the app somewhere near the top:
function App() { //declarations not shown
return (

News Headlines


//Remainder of app

);
}
For now, the component will appear in the page (see below) but do very little. Later, we will need to update the call to handle the submit event.
2

We now need to add some state to the SearchBar to hold our search terms. We’re going to keep the state inside the SearchBar because we don’t want to begin the search until the user presses the search button. So, go ahead and add some state at the top of the function. You should use the names [innerSearch, setInnerSearch] – the use of inner in innerSearch will be- come clear later. The initial value of innerSearch should be set to an empty string. The SearchBar state needs to talk to the input component. You have seen how to do this in the worksheet on forms. We need to ensure that the textbox display and the component state remain consistent. This requires that we set the input value and that we handle the change event.
But so far, all of this has focused on the SearchBar. We need a way to tell the news articles about our search – ultimately we need to hit the API with a query, and not just rely on the top stories as they come. For that, we’ll need to add some more state to our App component to hold the submitted search values. By now you should be noticing a pattern – we add some more state near the top of the relevant function via useState. Here, we insert a new line right at the top of the App function, and return [search, setSearch], where the search
3

is also set initially to hold an empty string.
The final stages of this worksheet involve plumbing – we need to pass the query text from the input through the SearchBar component so that it ultimately affects the state of the App. At that point, we will have to pass it to the component that talks to the News API.
We begin by attaching an onSubmit event handler to our SearchBar – we will use the setSearch function so we can update the state as soon as the user has pressed the Search button. It should now look like this: .
So, we are going to provide our event handler function to the SearchBar com- ponent via the parameters, but at this stage, the declaration of the SearchBar function doesn’t include any props. We need to fix this, and we then need to connect this handler so that it fires when the SearchBar search button is clicked.
Remember, the user will enter their search terms in the input field of the SearchBar, and this will be captured by innerSearch, the internal state of the SearchBar. So, when the button is clicked, we want to pass the innerSearch value to the onSubmit prop so that our App knows we’ve changed the value.
Your SearchBar should now look like this:
function SearchBar(props) {
const [innerSearch, setInnerSearch] = useState(”); return (

setInnerSearch(e.target.value)}
/>

);
}
As you know from the discussion above, the onSubmit handler is actually the setSearch state update method from the calling App, passed down to the
4

SearchBar via the props.
The challenge is to tell the news articles (and of course the API) that there is a
search term. For now, change this line:
const { loading, headlines, error } = useNewsArticles();
to this:
const { loading, headlines, error } = useNewsArticles(search);
As the search term is now available, open up the api.js file. We can now do something with the string.
Inside api.js, we first update the useNewsArticles function to accept a pa- rameter called search. You should also update the getHeadlines function to accept a similar search parameter. These changes are as simple as they sound.
Now, inside your useNewsArticles function, within the useEffect call, pass search to getHeadlines. As noted in the previous practical, you will need to pass search as a dependency to useEffect by adding it to the array. That way, every time the value of search changes, we’ll run the getHeadlines function again. The dependencies are specified in an array provided as the last argument of the useEffect function.
After these changes, your useNewsArticles should look like this:
export function useNewsArticles(search) {
const [loading, setLoading] = useState(true); const [headlines, setHeadlines] = useState([]); const [error, setError] = useState(null);
useEffect(() => { getHeadlines(search)
.then((headlines) => { setHeadlines(headlines); setLoading(false);
})
.catch((e) => {
setError(e);
setLoading(false); });
}, [search]);
return { loading,
headlines,
error, };
}
5

Inside getHeadlines, we will make use of the search parameter we added before and your method should look like this:
function getHeadlines(search) {
const url = `https://newsapi.org/v2/top-headlines?country=au&apiKey=${API_KEY}&q=${search}`;
return fetch(url)
.then((res) => res.json())
.then((res) => res.articles) // get just the list of articles .then((articles) =>
articles.map((article) => ({ title: article.title,
url: article.url,
})), );
}
You should now have a working search bar – here showing results for “Assange”:
If you check the docs for newsapi.org, you’ll see we can add a q (or query) param with a search term. This requires that we append &q=${search} at the
6

end of the url we created earlier. This will add our search terms or pass an empty query if there are none. Luckily, newsapi.org works correctly with an empty query. (Note that we are using the au country code).
When you enter text and hit submit, you will see a new list of articles that relate to your search term. At the time of writing, there was a relatively major story involving Julian Assange, and so that was the term I used in the example above.
Exercises:
• Add a ‘reset’ button to clear out the search terms
• Add an ‘empty state’ to display to users if there are no headlines that
match their search terms (currently this fails silently).
• Add a title to the top of the page the shows their search terms if there are
any, or ‘Top Headlines’ if there is no search. Bonus Points:
These additional exercises are a step up from the earlier work, but there for those who want a bit of a challenge.
• Highlight the part of the headline that matches the search term, if it’s there. This will be a pretty big job, but will be a good way to get more familiar with the approach. Note that newsapi.org also searches the text of the story, so you may not always have text to highlight.
• Search as the user types. Note: newsapi.org has a ‘rate limit’ so you’ll need to add “debouncing” or similar so you don’t hit the API too often. Google will be your friend here.
7