[英]React Hook [useState]: update state and rerender the view
經驗:我是 React 的初學者。
我正在嘗試學習: Hooks ( useState
) - 但我不知道如何更新狀態並用它重新渲染視圖。 據我了解,如果更新的狀態與上一個有點相似,React 不會重新渲染視圖......谷歌搜索后,我嘗試復制狀態並以某種方式更新它,但我錯過了一些東西,我不知道什么。
我在項目中嘗試做的事情:當用戶從下拉列表中選擇一個區域時,我有一個要過濾的國家/地區列表。 這是在選擇發生時被觸發的函數,以及我希望解釋我想要做什么的評論:
const change = event => {
//copy the `data` state (which has a list of all the countries)
let newData = [...data];
console.log(newData);
//filter through the countries list to get only those with the selected region
let filtered = newData.filter(obj => obj.region === event.target.value);
console.log(filtered);
//change the countries list with the filtered one, and rerender the view
setData([data, newData]);
console.log(data);
};
您可以在此處找到相關文件和代碼(向下滾動以訪問change
功能)
從“按區域篩選器”下拉列表中選擇一個區域
查看控制台中的錯誤/輸出
您正在將狀態更新為一組對象,最后一項將是過濾后的列表
相反,傳入一個包含過濾國家/地區的數組。
請注意,第二次選擇不同的地區時,您的狀態將丟失,因為您正在修改整個國家/地區集合。
setData(data.filter(obj => obj.region === event.target.value))
那么我們怎樣才能避免失去狀態呢?
我們可以根據所選區域過濾列表。
添加了我更改代碼的注釋
export default function CountriesList() {
const [data, setData] = useState([]);
const [distinctRegions, setDistinctRegions] = useState([]);
const [loading, setLoading] = useState(true);
// added state to track the selected region
const [selectedRegion, setSelectedRegion] = useState("");
useEffect(() => {
CountriesAPI().then(res => {
onLoad(res);
setLoading(false);
});
}, []);
const onLoad = dataList => {
setData(...data, dataList);
getRegions(dataList);
};
const getRegions = dataList => {
let regions = [];
dataList.map(dataItem =>
dataItem.region.length ? regions.push(dataItem.region) : ""
);
let regionsFiltered = regions.filter(
(item, index, arr) => arr.indexOf(item) === index
);
setDistinctRegions(...distinctRegions, regionsFiltered);
};
const renderLoading = () => {
return <div>Loading...</div>;
};
// now we only need to update the selected region
const change = event => {
setSelectedRegion(event.target.value);
};
const renderData = (dataList, distinctRegionsItem) => {
if (dataList && dataList.length) {
return (
<div>
<Container>
<Input type="text" placeholder="Search for a country..." />
<Select className="select-region" onChange={change}>
<option value="" hidden>
Filter by region
</option>
// added show all
<option value="">Show All</option>
{distinctRegionsItem.map(item => {
return (
<option key={item} value={item}>
{item}
</option>
);
})}
</Select>
</Container>
<CardList>
// filter the array based on selectedRegion and then render the list.
// if selectedRegion is empty show all
{dataList
.filter(
country => !selectedRegion || country.region === selectedRegion
)
.map(country => (
<CountryCard
population={country.population}
region={country.region}
capital={country.capital}
flag={country.flag}
key={country.alpha3Code}
id={country.alpha3Code}
name={country.name}
/>
))}
</CardList>
</div>
);
} else {
return <div>No items found</div>;
}
};
return loading ? renderLoading() : renderData(data, distinctRegions);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.