Как использовать условный рендеринг внутри карты в React

#javascript #reactjs

Вопрос:

У меня есть страница react, которая отображает список продуктов, возвращаемых из GraphQL API. Как только продукты будут возвращены, я сохраняю их в состоянии, а затем визуализирую их. Как мне отображать только те продукты, которые соответствуют определенным условиям?

Прямо сейчас я сопоставляю продукты и визуализирую каждый из них. Это работает правильно. Но если я пытаюсь использовать условные операторы, я получаю ошибки в своей IDE. Это код, который у меня есть в настоящее время. В настоящее время это работает:

 async function contactAPI() {
  return await axios({
    url: 'https://graphqlexample.com/api/products',
    method: 'post',
    data: {
      query: `
      QUERY GOES HERE
        `
    }
  })
}

function App() {  
  const [products, setProducts] = useState([]);

  useEffect(() => {
    async function getData() {
      const res = await contactAPI();
      setProducts(res.data.data.products);
    }
    getData();
  }, []);

  return (
    <div>
        <div>          
          {products.map(p =>           
          (             
          <div>            
            <ProductCard productName={p.productName} />
          </div>
          ))}
        </div>    
    </div>
  );
} 
 

Мне p.productName нужно проверить, соответствует ли он определенным условиям, и если соответствует, визуализируйте его. Если нет, не выполняйте рендеринг. Я пытался использовать разные условные обозначения внутри map , но продолжал получать ошибки.

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

1. Какие ошибки вы получаете?

Ответ №1:

map всегда будет возвращать массив одинаковой длины, поэтому вы будете возвращать некоторые пустые элементы в зависимости от условия, которое не является оптимальным.

Вместо filter этого сначала данные, а затем map возвращаемый массив. Таким образом, вы отображаете только те данные, которые вам нужно отобразить.

 const { useState } = React;

function App({ data }) {

  const [ products, setProducts ] = useState(data);

  // In this example we take the list of products in
  // state and return a new array of only those products
  // that aren't soap. We then `map` over that array in our
  // component render
  function getFilteredProducts() {
    return products.filter(product => {
      const name = product.productName.toLowerCase();
      return !name.includes('soap');
    });
  }

  // Get an array of filtered products and then `map` over it
  // to produce the product cards
  return (
    <div>
      {getFilteredProducts().map(product => {
        return (
          <ProductCard
            key={product.id}
            id={product.id}
            name={product.productName}
          />
        );
      })}
    </div>
  );
};

function ProductCard({ id, name}) {
  return <div>{id}: {name}</div>;
}

const data=[{id:1,productName:"Blue Soap"},{id:2,productName:"Beans"},{id:3,productName:"Green Soap"},{id:4,productName:"Sponge"},{id:5,productName:"Chicken"}];

ReactDOM.render(
  <App data={data} />,
  document.getElementById('react')
); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div> 

Ответ №2:

В качестве примера вы можете просто вернуть JSX , если он будет соответствовать определенному критерию, как:

Примечание: для демонстрации я использовал includes метод. Вы можете указать условие

 (<div><ProductCard productName={p.productName} /></div>)
 

и будет отображаться только в том случае, если первое условие true

   <div>
    {products.map((p) => (
      p.productName.includes("free") amp;amp; (<div><ProductCard productName={p.productName} /></div>)
    ))}
  </div>
 

Демонстрация Codesandbox

 export default function App() {
  const arr = [1, 2, 3, 4, 5];
  return (
    <div>
      {arr.map((n) => {
        return n % 2 === 0 amp;amp; <div key={n}>{n}</div>;
      })}
    </div>
  );
}
 

Ответ №3:

 {
    products.map(id => {
      return condition == true ?
        <div>            
          <ProductCard productName={p.productName} />
        </div>
    : <div></div>
})}
 

Ответ №4:

 const products = [
  { productName: "product1" },
  { productName: "product2" },
  { productName: "product3" }
];

const App = () => {
  return (
    <div className="App">
      <div>
        {products.map((p, index) => {
          if (p.productName === "product1") {
            return <div key={index}>{p.productName}</div>;
          }
          return <React.Fragment></React.Fragment>;
        })}
      </div>
    </div>
  );
}

ReactDOM.render(
    <App />,
    document.getElementById("react")
); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>