如何解决我可以从 ReactJS 中的父元素检索属性值吗?
当我单击特定按钮时,我想捕获与其关联的 {country} 道具。 我累了以下
import React,{ useState,useEffect } from 'react'
import axios from 'axios'
// ====================================================================[SEARCH-BAR]=======================================================
// search component
const SearchBar = (props) => {
// console.log(props);
const { searchString,searchOnChangeEventHandler } = props
return (
<>
<form>
<label>Search </label>
<input type='text' placeholder='type to search...' value={searchString} onChange={searchOnChangeEventHandler} />
</form>
</>
)
}
// ================================================================[COUNTRY_CARD]==========================================================
// countryCard component
const CountryCard = (props) => {
console.log(props);
return (
<div>
<p>countryName</p>
<p>capital</p>
<p>population</p>
<p>languages</p>
<ul>
<li>item</li>
<li>item</li>
</ul>
<p>image flag</p>
</div>
)
}
// ===================================================================[disPLAY]===========================================================
// display component
const display = (props) => {
const [showCountryCard,setShowCountryCard] = useState(false)
const [thisCountry,setThisCountry] = useState({})
// console.log(props);
const { countries,searchString } = props
// console.log(countries);
// eslint-disable-next-line eqeqeq
// searchString empty
if (searchString == false) {
return (
<>
<div>
<span>Type in SearchBar for a country...</span>
</div>
</>
)
}
// to count number of matches
const filteredResultsCount = countries.filter(country => country.name.toLowerCase().includes(searchString.toLowerCase())).length
// function to filterCountries
const filteredResults = (searchString,countries) => countries.filter(country => {
return country.name.toLowerCase().includes(searchString.toLowerCase())
})
// RENDER CONDITIONS
// searchString return <= 10 matches && >1 match
// event handler for show-btn
const showCardEventHandler = (event) => {
console.log(event.target.parentElement);
setShowCountryCard(!showCountryCard)
}
if (filteredResultsCount <= 10 && filteredResultsCount > 1) {
return (
<>
<ul>
{
filteredResults(searchString,countries).map(country =>
<li
key={country.numericCode}
country={country}
>
<span>{country.name}</span>
<button
value={showCountryCard}
onClick={showCardEventHandler}
>show</button>
</li>
)
}
</ul>
{
showCountryCard ? <p>show country card</p> : null
}
</>
)
}
// searchString returns >10 matches
if (filteredResultsCount > 10) {
return (
<span>{filteredResultsCount} matches!,please refine your search...</span>
)
}
// searchString returns ===1 match
if (filteredResultsCount === 1) {
return (
<>
{
filteredResults(searchString,countries).map(country => <CountryCard key={country.numericCode} country={country} />)
}
</>
)
}
// invalid searchString
if (filteredResultsCount === 0) {
return (
<span><strong>{filteredResultsCount} matches!</strong> please refine your search...</span>
)
}
}
// ===================================================================[APP]==============================================================
// app component
const App = () => {
// to store countries
const [countries,setCountries] = useState([])
// to fetch data from
const url = 'https://restcountries.eu/rest/v2/all'
useEffect(() => {
// console.log('effect');
axios
.get(url)
.then(response => {
// console.log('promise fulfilled');
const countries = response.data
// array of objects
setCountries(countries)
})
},[])
// console.log('countries',countries.length);
// console.log(countries);
// to store search string
const [searchString,setSearchString] = useState('')
// event handler search input
const searchOnChangeEventHandler = (event) => setSearchString(event.target.value)
return (
<>
<h1>Countries Data</h1>
<SearchBar searchString={searchString} searchOnChangeEventHandler={searchOnChangeEventHandler} />
<br />
<display countries={countries} searchString={searchString} />
</>
)
}
export default App
请查看 <display/>
组件,特别是我正在尝试处理这部分
const showCardEventHandler = (event) => {
console.log(event.target.parentElement);
setShowCountryCard(!showCountryCard)
}
if (filteredResultsCount <= 10 && filteredResultsCount > 1) {
return (
<>
<ul>
{
filteredResults(searchString,countries).map(country =>
<li
key={country.numericCode}
country={country}
>
<span>{country.name}</span>
<button
value={showCountryCard}
onClick={showCardEventHandler}
>show</button>
</li>
)
}
</ul>
{
showCountryCard ? <p>show country card</p> : null
}
</>
)
}
我希望能够呈现超过 10 个国家/地区的列表,并允许用户单击特定国家/地区,然后将用于呈现 <CountryCard/>
组件。
如果搜索中只有 1 个匹配值,那么我将直接显示国家/地区卡片组件。第二个功能有效。
在以下重构之后,第一个功能有效,但我有点困惑为什么所以我添加到帖子中。这是正在呈现的组件,现在我正在传递国家道具 onClick,就像这样
if (filteredResultsCount <= 10 && filteredResultsCount > 1) {
return (
<>
<ul>
{filteredResults(searchString,countries).map((country) => (
<li key={country.numericCode} country={country}>
<span>{country.name}</span>
<button
value={showCountryCard}
onClick={() => toggleCardEventHandler(country)}>
{showCountryCard ? 'hide' : 'show'}
</button>
</li>
))}
</ul>
{showCountryCard ? <CountryCard country={country} /> : null}
</>
);
}
事件处理程序如下
const toggleCardEventHandler = (country) => {
// console.log(country);
setShowCountryCard(!showCountryCard);
setCountry(country)
};
这可以正常工作。
我的问题是,当我更改 eventHandler onClick={toggleCardEventHandler(country)}
时,它会中断,但不应该通过关闭来访问它吗?
另外,如果我把代码改成这样
onClick={() => {
toggleCardEventHandler()
setCountry(country)
}}
代码按照我想要的方式工作,但哪个更好的方法是将值传递给 toggleCardEventHandler()
并在那里设置国家/地区,或者像这样这样做?
解决方法
据我所知,您希望将 country.name
传递给您的 showCardEventHandler。
更新 showCardEventHandler
以获取事件和国家/地区名称:
const showCardEventHandler = (event,countryName) => {
console.log(countryName);
setShowCountryCard(!showCountryCard)
}
现在将国家名称传递给函数:
<li
key={country.numericCode}
country={country}
>
<span>{country.name}</span>
<button
value={showCountryCard}
onClick={e => showCardEventHandler(e,country.name)}
>show</button>
</li>
由于您没有在 showCardEventHandler
中使用该事件,您可以将其从签名中删除
const showCardEventHandler = (countryName) => {}
并用 onClick={() => showCardEventHandler(country.name)}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。