Почему мои переменные внутри тегов HTML не отображаются? - PullRequest
0 голосов
/ 10 июля 2020

Я пытаюсь сделать компонент для отображения случайных продуктов из массива. Когда я console log props.products[random].company или любой другой атрибут, я вижу их в консоли. Но когда я помещаю их в теги HTML, он не отображается.

Длина массива равна 14. Отображаются случайные числа, но иногда они больше 14 и кажутся по какой-то причине.

Это файл компонента:

import React, { useEffect } from 'react';
import Link from 'react-router-dom';
import { connect } from 'react-redux';
import { getProducts } from '../../../actions/productsActions';
export const ProductSm = (props) => {
  console.log(props.products);

  return (
    <div>
      {
       props.products.length >= 1 && setInterval(() => {
  
          let random = Math.floor(Math.random()*props.products.length);
          console.log(random);
          console.log(props.products[random].company);
          return (
                <div>
                  <p>{props.products[random].company}</p>
                  <p>{props.products[random].name}</p>
                  <img src={`http://localhost:5000/${props.products[random].productImage}`} alt="productImage"/>
                </div>)
        }, 5000)
      }
    </div>
  )
}

const mapStateToProps = (state) => ({
  products: state.products.products,
  loading: state.products.products
})

export default connect(mapStateToProps, {getProducts})(ProductSm);

А это компонент, содержащий ProductSm. js:

import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { getProducts, setLoading } from '../../../actions/productsActions';
import { connect } from 'react-redux';
import {Link} from 'react-router-dom';
import './Home.css';
import Loading from './Loading';
import Navbar from './Navbar';
import ProductSm from './ProductSm';
export const Home = (props) => {
  useEffect(() => {
    props.setLoading();
    props.getProducts();
    //eslint-disable-next-line
    console.log(props.products);
    console.log(props.loading);
  }, []); 
  if(props.loading) {
    return <Loading />
  }
  else {
    
  return (
      <div>
        <Navbar />
        <div className="home">
          <div className="group-1">
            <div className="branding">
              <div className="brandName">
                The
                <br/>
                Sole
                <br/>
                Store
              </div>
              <div>
                  <p>The finest designs and fits.</p>
              </div>
            </div>
            <div className="viewProducts">
              <div>
                <p>
                  Check out our latest and greatest models
                </p>
                <Link className="productsBtn" to="/shoes">GO <i className="fas fa-arrow-right"/></Link>
              </div>
            </div>
          </div>
          <div className="group-2">
            <div className="products">
                <ProductSm />
                <ProductSm />
                <ProductSm />
                <ProductSm />
            </div>
            <div className="something"></div>
            </div>
        </div>
      </div>
  )
}
}
Home.propTypes = {
  products: PropTypes.array.isRequired,
  loading: PropTypes.bool.isRequired
}

const mapStateToProps = state => ({
  products: state.products.products,
  loading: state.products.loading
});

export default connect(mapStateToProps, {getProducts, setLoading})(Home);

Буду очень признателен за любую помощь. Спасибо enter image description here

введите описание изображения здесь

Ответы [ 2 ]

0 голосов
/ 10 июля 2020

Вот код, который должен работать:

import React, { useEffect, useState } from "react";
import Link from "react-router-dom";
import { connect } from "react-redux";
import { getProducts } from "../../../actions/productsActions";

export const ProductSm = (props) => {
  const [randomProductIndex, setRandomProductIndex] = useState();

  useEffect(() => {
    if (props.products.length >= 1) {
      const interval = setInterval(() => {
        const randomIndex = Math.floor(Math.random() * props.products.length);

        setRandomProductIndex(randomIndex);
      }, 5000);

      return () => clearInterval(interval);
    }
  }, [props.products.length]);

  return (
    <div>
      <p>{props.products[randomProductIndex].company}</p>
      <p>{props.products[randomProductIndex].name}</p>
      <img
        src={`http://localhost:5000/${props.products[randomProductIndex].productImage}`}
        alt="productImage"
      />
    </div>
  );
};

const mapStateToProps = (state) => ({
  products: state.products.products,
  loading: state.products.products,
});

export default connect(mapStateToProps, { getProducts })(ProductSm);

Объяснение:

Ошибка в основном в этой строке:

props.products.length >= 1 && setInterval(...)

Если левая сторона оператора && истинно, он вернет все, что вернет правая сторона. Метод setInterval возвращает число, которое идентифицирует этот интервал, поэтому вы можете отменить его с помощью clearInterval(number). Возврат чего-либо из setInterval не имеет никакого эффекта.

0 голосов
/ 10 июля 2020

В настоящее время вы возвращаете результат setInterval, а не какой-либо JSX:

return (
    <div>
      {
       props.products.length >= 1 && setInterval(() => {

Функция, переданная в setInterval, вызывается асинхронно (в данном случае через 5000 мс). Таким образом, вы на самом деле ничего не возвращаете для рендеринга.

Вместо этого вы, вероятно, захотите отслеживать случайное число как состояние и запускать повторный рендеринг каждые 5000 мс

...