curriculum/challenges/english/blocks/workshop-fruit-search-app/67ed044dc76cf4a441618f2c.md
In React, <dfn>controlled inputs</dfn> are a standard way to handle form data, where the input's value is synced with the component's state.
const MyForm = () => {
const [name, setName] = useState("");
return (
<>
<label htmlFor="name">Your name</label>
<input type="text" value={name} id="name" />
</>
);
}
You will learn more about this pattern in a future lesson.
To track what the user types into the search input field, create a state variable named query with an initial value of an empty string (''). Also define its corresponding setter function, setQuery, using the useState Hook.
You should use the array destructuring syntax for the query and setQuery variables.
assert.match(code, /(const|let|var)\s+\[\s*query\s*,\s*setQuery\s*\]\s*/);
You should use the useState Hook.
const abuseState = __helpers.spyOn(React, "useState");
const script = [...document.querySelectorAll("script")].find((s) => s.dataset.src === "index.jsx").innerText;
const exports = {};
const _a = eval(script);
const _b = await __helpers.prepTestComponent(exports.FruitsSearch);
assert.isAtLeast(abuseState.calls.length, 1);
Your useState Hook should have an initial value of an empty string ('').
const abuseState = __helpers.spyOn(React, "useState");
const script = [...document.querySelectorAll("script")].find((s) => s.dataset.src === "index.jsx").innerText;
const exports = {};
const _a = eval(script);
const _b = await __helpers.prepTestComponent(exports.FruitsSearch);
assert.equal(abuseState.calls[0]?.[0], '');
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Fruits Search</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.3.1/umd/react.development.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.3.1/umd/react-dom.development.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/7.26.5/babel.min.js"></script>
<script
data-plugins="transform-modules-umd"
type="text/babel"
src="index.jsx"
></script>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<div id="root"></div>
<script
data-plugins="transform-modules-umd"
type="text/babel"
data-presets="react"
data-type="module"
>
import { FruitsSearch } from './index.jsx';
ReactDOM.createRoot(document.getElementById('root')).render(<FruitsSearch />);
</script>
</body>
</html>
body {
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f4f4f4;
}
#search-container {
text-align: center;
background: white;
padding: 20px;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
#search-input {
padding: 10px;
width: 80%;
border: 1px solid #ccc;
border-radius: 5px;
margin-bottom: 10px;
}
#results {
text-align: left;
max-height: 150px;
overflow-y: auto;
}
.result-item {
padding: 5px;
border-bottom: 1px solid #ddd;
}
const { useState, useEffect } = React;
export function FruitsSearch() {
--fcc-editable-region--
--fcc-editable-region--
return (
<div id="search-container">
<form>
<label htmlFor="search-input">Search for fruits:</label>
<input
id="search-input"
type="search"
/>
</form>
</div>
);
}