Условный рендеринг компонента React при наличии ключа json

#reactjs #components #conditional-statements

#reactjs #Компоненты #условные операторы

Вопрос:

Я пытаюсь условно отобразить компонент с плохими результатами. Я прочитал много руководств и вопросов о переполнении стека, но я не могу получить эту работу. Не могли бы вы мне помочь?

Условный компонент представляет собой географическую карту визуализации данных, которая должна отображаться только тогда, когда выбранный файл json имеет ключ «code». Другими словами, у меня есть десятки json, и некоторые из них содержат информацию о географических картах, но не все. Я пробовал логические и другие типы троичных операторов в jsx, но каждый раз, когда на боковой панели нажимается элемент без отображения, React пытается отобразить дочерний компонент Map и выдает ошибку, что «код» (ключ) не определен. Что может быть причиной этого? Ниже приведен мой код:

App.js

 function App() {
  const [files, setFiles] = useState([]);
  const [items, setItems] = useState([]);
  const [product_id, setProduct_id] = useState(13);
  const [mapCode, setMapcode] = useState(0);

  useEffect(() => {
    fetch("/sidebar")
      .then((res) => res.json())
      .then((data) => {
        setItems(data);
      });
  }, []);

  useEffect(() => {
    fetch(`/data/${product_id}`)
      .then((res) => res.json())
      .then((data) => {
        setFiles(data);
        if ("code" in data[0]) setMapcode(1);
        else setMapcode(0);
        console.log(mapCode);
      });
  }, [product_id]);

 function HandleSelection(e) {
    setProduct_id(e);
  }

  

Внутри useEffect, если извлеченные данные продукта содержат ключ «code», я меняю mapCode каждый раз, когда элемент (продукт) нажимается на боковой панели. console.log(mapCode) дает правильные результаты.

Ниже приведен основной код внутри return() для App.js . Есть несколько способов, которыми я пытался заставить условный рендеринг работать.

 
<div className="col-6">
    <Files files={files} />
</div>
<div className="col-3">
         
    {/*Boolean(mapCode) amp;amp; <Map files={files} />*/}
    {/*mapCode === true amp;amp; <Map files={files} />*/}
    mapCode === true ? <Map files={files} /> : <div>No map</div>

</div>
  

Мне было интересно, подходит ли useEffect для использования setMapcode (0) и setMapcode (1)?

Ответ №1:

Сначала вы должны установить логическое значение isMapCode вместо числа:

 const [isMapCode, setIsMapcode] = useState(false);

useEffect(() => {
  fetch(`/data/${product_id}`)
    .then((res) => res.json())
    .then((data) => {
      setFiles(data);
      setIsMapcode(data[0].code !== undefined);
    });
}, [product_id]);
  

Поэтому вы должны проверить его значение внутри scope ( {} ):

 <div className="col-3">
  {isMapCode ? <Map files={files} /> : <div>No map</div>}
</div>
  

Обратите внимание, что для этого вам не нужно другое состояние, вы можете проверить свое files состояние:

 const isMapCodeAvailable = data[0].code !== undefined;
<div className="col-3">
  {isMapCodeAvailable ? <Map files={files} /> : <div>No map</div>}
</div>
  

Комментарии:

1. Спасибо. Я последовал первому вашему пути setIsMapcode(data[0].includes("code")); и получил ошибку: необработанное отклонение (ошибка типа): данные [0].includes не является функцией . Вторым способом const isMapCodeAvailable = files[0].includes("code"); я получил ошибку типа: files[0] не определено . Почему files[0] -то недоступен. Я написал const isMapCodeAvailable = files[0].includes('code'); в начало функции App() после объявления состояний. Это было правильное место?

2. Вам не нужно копировать и вставлять решение, просто поймите концепцию. Я не знаю, как выглядят ваши данные.

3. Основная проблема вашего кода в том, что вы не использовали область видимости внутри JSX {} , и я думаю if ("code" in data[0]) , что data[0] является массивом? Или вы проверяете, существует ли ключ

4. Я думал data[0] , что это массив, вы просто можете сделать data[0].code !== undefined или "code" in data[0] как вы сделали