Существует руководство React по этой конкретной c проблеме: Подъем состояния .
Обычно вы управляете состоянием в родительском элементе. В данном случае App
, где вы управляете состоянием текста поиска. Вы передаете функцию компонентам, чтобы изменить это состояние. Компоненты, которые зависят от этого состояния, передают значение через свойства.
Вот пример:
const {useEffect, useState} = React;
function App() {
const episodesURL = "https://rickandmortyapi.com/api/episode";
const [page, setPage] = useState(1);
const [pageInfo, setPageInfo] = useState({});
const [searchText, setSearchText] = useState("");
const [episodes, setEpisodes] = useState([]);
useEffect(() => {
const url = new URL(episodesURL);
url.searchParams.set("page", page);
if (searchText) url.searchParams.set("name", searchText);
fetch(url)
.then(response => response.json())
.then(response => {
if (response.error) {
setPageInfo({});
setEpisodes([]);
} else {
setPageInfo(response.info);
setEpisodes(response.results);
}
});
}, [page, searchText]);
const search = searchText => {
setSearchText(searchText);
setPage(1);
};
return (
<div>
<CustomNavbar search={search} />
<Episodes episodes={episodes} />
<Pagination setPage={setPage} info={pageInfo} />
</div>
);
}
function CustomNavbar({search}) {
const [searchText, setSearchText] = useState("");
const handleFormSubmit = event => {
event.preventDefault();
search(searchText);
};
return (
<form onSubmit={handleFormSubmit}>
<input
type="text"
placeholder="search"
value={searchText}
onChange={event => setSearchText(event.target.value)}
/>
<button type="submit">Search</button>
</form>
);
}
function Episodes({episodes}) {
return (
<table>
<thead>
<tr>
<th>episode</th>
<th>name</th>
<th>air date</th>
</tr>
</thead>
<tbody>
{episodes.map(episode => (
<tr key={episode.id}>
<td>{episode.episode}</td>
<td>{episode.name}</td>
<td>{episode.air_date}</td>
</tr>
))}
</tbody>
</table>
);
}
function Pagination({setPage, info}) {
return (
<div>
{info.prev && <a onClick={() => setPage(page => page - 1)}>previous</a>}
{info.next && <a onClick={() => setPage(page => page + 1)}>next</a>}
</div>
);
}
ReactDOM.render(<App />, document.getElementById("root"));
th { text-align: left; }
a { cursor: pointer; }
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>