У меня есть родительский компонент, у которого есть div, содержащий ol с пользовательскими компонентами внутри. Каждый из этих компонентов имеет состояние, в котором я сохраняю логическое значение «check». Мне нужна кнопка в моем родительском компоненте, которая очистит ВСЕ состояние дочерних компонентов и установит для него значение false. Я пытаюсь использовать useRef и useImperativeHandle, но не могу понять.
CountryListing (дочерний компонент)
export default function CountryListing({ country }, ref) {
const countryRef = useRef();
const [checkbox, toggleCheckbox] = useState(false)
const clearCheckbox = () => {
toggleCheckbox(false);
}
useImperativeHandle(ref, () => ({
clear: () => {ref.current.clearCheckbox()}
}
));
return (
<li key={country} >
<div className="country-listing-container">
<input type="checkbox" className="country-checkbox" id={country + "Checkbox"} ref={countryRef} value={checkbox} onChange={() => toggleCheckbox(!checkbox)}></input>
<img src={'https://storage.googleapis.com/flags-bucket/flags/' + getImageFor(country)} className="country-flag" alt={country + "'s flag icon."}></img>
<p className="country-name"> {country} </p>
</div>
</li>
);
}
Сворачиваемый (родительский компонент)
export default function Collapsible() {
const [open, togglePanel] = useState(false);
const [countries] = useState(["Mexico", "Brazil", "United Kingdom", "Not Provided - Canada", "United States", "Russia", "Australia", "Peru", "China", "Taiwan", "Pakistan", "Yemen", "Thailand", "New Zealand", "Czech Republic", "Spain", "Japan", "South Korea", "South Africa", "Argentina", "Afghanistan", "Angola", "Andorra", "Armenia", "Fiji", "Finland", "Estonia", "Ecuador", "Egypt", "Hungary", "Iran", "Ireland", "Austria", "Poland", "Kuwait", "Libya", "Monaco", "Mongolia", "Mozambique", "Nepal", "Italy", "Norway", "Barbados", "Bolivia", "Bulgaria", "Chile", "Colombia"]);
const [searchTerm, setSearchTerm] = useState('');
const [searchResults, setSearchResults] = useState(countries);
//TODO title is not showing completely
const [title] = "Locations";
const ref = useRef(false);
const countryComponents = (countries) => {
const countriesList = countries.map(thisCountry => <CountryListing country={thisCountry} ref={ref} />);
return countriesList;
}
const [countryComponentsList, modifyCountryComponentsList] = useState(countryComponents(searchResults))
const clearAllAction = () => {
ref.current.clearCheckbox();
}
const Initials = (countries) => {
const [countryInitials] = useState(getInitials(countries.countries));
const listInitials = countryInitials.map((initial) => <li key={initial}> {initial} </li>);
return (
<ul style={{ listStyleType: "none" }}>{listInitials}</ul>
)
}
const search = (term) => {
console.log('searchTerm is ' + searchTerm);
if (!term) {
setSearchResults(countries);
}
else {
const results = countries.filter(country => country.toLowerCase().includes(term));
setSearchResults(results);
}
}
return (
<>
<div className="top-header">
<input type="text" placeholder="Filter Locations" value={searchTerm}
onKeyUp={(event) => {
setSearchTerm(event.target.value);
search(searchTerm);
}}
onChange={(event) => {
setSearchTerm(event.target.value);
search(searchTerm);
}}
onLoad={(event) => {
setSearchTerm(event.target.value);
search(searchTerm);
}}
>
</input>
<button onClick={() => search(searchTerm)}> S </button>
</div>
<div>
<div onClick={() => togglePanel(!open)} className="header">
{title}
</div>
{
open ? (
<>
<div className="before-content"><button id="clearAllButton" onClick={clearAllAction()} > X Clear All </button></div>
<div className="content">
<div className="basic-grid">
<div className="card">
<ol style={{ listStyleType: "none" }}>
{countryComponentsList}
</ol>
</div>
<div className="card">
<Initials countries={countries} />
</div>
</div>
</div>
</>
) : null
}
</div >
</>
);
}
Я пытался найти ответ, но мне ничего не помогает понять его, и обычно упоминаются отдельные компоненты. Хотя я понимаю, что мне нужно реализовать это для одного компонента, а затем сопоставить их.