#javascript #reactjs #react-redux
#javascript #reactjs #реагировать-redux
Вопрос:
Итак, у меня есть эти тестовые фиктивные данные здесь:
{
_id: "1",
name: "Lakawon Island Resort",
price_per_night: 2804.0,
description:
"On a lush 16-hectare island with white-sand beaches, this relaxed resort is 5 km from the jetty in Cadiz Viejo, a village on the mainland.",
address: "Cadiz Viejo",
city: "New York",
state: "New York",
zip_code: "6121",
latitude: 11.045411,
longitude: 123.201465,
phone: "(034) 213 6354",
email: "info@example.com",
website: 'www.lakawonislandresort.us',
amenities:
{
tv: false,
reservation: false,
cabin: true,
services: true,
},
image:
"https://images.unsplash.com/photo-1512356181113-853a150f1aa7",
rating: 4.5,
reviews: 11,
},
Обратите внимание, что у меня есть этот объект amenities
, который также является объектом. В настоящее время у меня есть 4 вложенных объекта tv
, reservation
, cabin
и services
.
Что мне нужно, так это проверить каждый элемент, если они истинны, если они действительно истинны, затем верните ключ объекта и добавьте рядом с ним значок с потрясающим шрифтом. В противном случае, если значение равно false, ничего не делайте или возвращайте null.
Пока вот как я это реализовал:
{
amenities amp;amp; Object.entries(amenities).map(
([key, value]) => {
if(key === 'tv' amp;amp; key[value] === true){
return `<p><i class="fa fa-tv"></i> ${key}</p>`
} else if (key === 'reservation' amp;amp; key[value] === true){
return `<p><i class="fa fa-reservation"></i> ${key}</p>`
}else if (key === 'cabin' amp;amp; key[value] === true){
return `<p><i class="fa fa-cabin"></i> ${key}</p>`
}else if (key === 'services' amp;amp; key[value] === true){
return `<p><i class="fa fa-service"></i> ${key}</p>`
}
return null
}
)
}
Однако это не сработало, вместо этого оно возвращает Can't map through object
ошибку.
Есть идеи, как я могу проверить каждый ключ, если они истинны, а затем вывести их соответствующий значок fontawesome рядом с ним, если значение равно true? Есть ли более эффективный способ сделать это, чем оператор if else?
Вот полный код для этого компонента:
const Beach = ({ match }) => {
const [resort, setResort] = useState({})
useEffect(() => {
const fetchBeach = async () => {
const { data } = await axios.get(`/api/resorts/${match.params.id}`)
setResort(data)
}
fetchBeach()
}, [match])
const { name, address, city, province, zip_code, image, description, amenities, website, phone, email } = resort
return (
<div className="row mt-5">
<div className="col-lg-7">
<h1>{name}</h1>
<p><FaMapMarkerAlt /> {`${address}, ${city} ${province}, Philippines, ${zip_code}`}</p>
<img src={image} alt={name} width="700" />
<br/>
<p>{description}</p>
<br/>
<h4>Amenities:</h4>
<div>
{
amenities amp;amp; Object.entries(amenities).map(
([key, value]) => {
if(key === 'tv' amp;amp; key[value] === true){
return `<p><i class="fa fa-tv"></i> ${key}</p>`
} else if (key === 'reservation' amp;amp; key[value] === true){
return `<p><i class="fa fa-reservation"></i> ${key}</p>`
}else if (key === 'cabin' amp;amp; key[value] === true){
return `<p><i class="fa fa-cabin"></i> ${key}</p>`
}else if (key === 'services' amp;amp; key[value] === true){
return `<p><i class="fa fa-service"></i> ${key}</p>`
}
return null
}
)
}
</div>
</div>
</div>
)
}
export default Beach
Ответ №1:
Вы можете сделать что-то более сокращенное
{amenities amp;amp;
Object.keys(amenities)
.filter((key) => amenities[key])
.map((key) => {
if (key === "tv") {
return (
<p>
<i class="fa fa-tv"></i> {key}
</p>
);
} else if (key === "reservation") {
return (
<p>
<i class="fa fa-reservation"></i> {key}
</p>
);
} else if (key === "cabin") {
return (
<p>
<i class="fa fa-cabin"></i> {key}
</p>
);
} else if (key === "services") {
return (
<p>
<i class="fa fa-service"></i> {key}
</p>
);
}
})}
Ознакомьтесь с текущим codesandbox, который я создал: https://codesandbox.io/s/optimistic-darkness-yt9sy?file=/src/Beach.js
Почему и как:
В принципе, если вам нужно только проверить, является ли ваш key === ‘something’ и проверить, является ли значение true или false, вы могли бы сделать это так:
Сначала отфильтруйте объект, чтобы он сохранял только истинные значения. Затем в вашем .map() вы узнаете, что получаете правдивые ключи, поэтому вы просто обрабатываете условный рендеринг на основе значения ключа
.filter((key) => amenities[key]) // will filter out every values not truthy
myCurrentKey: » // будет отфильтрован
myCurrentKey: 1 // не будет отфильтрован
Кроме того, с моей точки зрения, когда у вас есть объект, который вы хотите отобразить, попробуйте сначала использовать Object.keys().map() , это самый простой и понятный способ сделать, если вам не нужно что-то действительно нестандартное, вы могли бы сделать с Object.entries ,или иначе.
Комментарии:
1. Ошибка типа: невозможно преобразовать undefined или null в object
2. Также в вашей песочнице кода он возвращает текст
<p><i class="fa fa-cabin"></i> cabin</p><p><i class="fa fa-service"></i> services</p>; }
вместо форматированного HTML3. Что касается первого комментария, то, поскольку вы не можете отобразить что-то нулевое, вам нужно вернуть пустую строку. Во-вторых, это потому, что в вашем первом коде вы вернули строку шаблона, когда вам просто нужно вернуть html напрямую без строки. Вот и все
Ответ №2:
Это можно сделать и таким образом:
const { amenities = {} } = resort;
return (
<div>
{Object.keys(amenities).map(item => {
return amenities[item] ? <p><i class={`fa fa-${item}`}></i>{item}</p> : null;
})}
</div>
)
Но я думаю, что отображение здесь на самом деле не нужно, и вы можете просто упростить его:
const { amenities = {} } = resort;
return (
<div>
{amenities.tv amp;amp; <p><i class="fa fa-tv"></i>tv</p>}
{amenities.reservation amp;amp; <p><i class="fa fa-reservation"></i>reservation</p>}
{amenities.cabin amp;amp; <p><i class="fa fa-cabin"></i>cabin</p>}
{amenities.services amp;amp; <p><i class="fa fa-service"></i>services</p>}
</div>
)
Ответ №3:
Попробуйте это:
amenities amp;amp; Object.entries(amenities).filter(([key,value]) => value === true).map(
([key]) => {
switch(key){
case 'tv':
return <p><i class="fa fa-tv"></i> {key}</p>;
case 'reservation':
return <p><i class="fa fa-reservation"></i> {key}</p>;
case 'cabin':
return <p><i class="fa fa-cabin"></i> {key}</p>;
case 'services':
return <p><i class="fa fa-services"></i> {key}</p>;
default:
return null;
}
})
Я думаю, ваша проблема в том, что вы используете key[value]
when key
— строка и value
является логическим значением
Комментарии:
1. Он возвращает текст, а не тег абзаца. Вот что его возвращает
<p> tv</p><p>reservation</p>
Это должен быть абзац а не написанный html текст2. Вы правы, я этого не заметил. попробуйте обновленный код прямо сейчас