首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在react中从呈现函数内部setState

如何在react中从呈现函数内部setState
EN

Stack Overflow用户
提问于 2021-02-19 16:51:44
回答 1查看 143关注 0票数 0

我知道您应该保持呈现函数的纯正性,但是我有一个特殊情况,需要传递一些值并更新呈现函数中的状态,但是我得到了以下错误消息:

不能在现有状态转换期间更新(例如在render中)。呈现方法应该是道具和状态的纯函数。

代码:

代码语言:javascript
复制
import Carousel from 'react-elastic-carousel';
import top from '../images/top.png';
import ArrowRight from '../images/arrowRight.svg';
import React, {Component} from 'react';
class contentSlider extends Component {

  state = {
    disabled: '',
    leftArrow: false,
    rightArrow: true
  }

  sliderData = [
    {
      title: 'POLO',
      typeOfcontent: 'Mens T-Shirt',
      rrp: '£105',
      ourPrice: '£55',
      salePrice: '£45',
      image: top
    },
    {
      title: 'POLO',
      typeOfcontent: 'Mens T-Shirt',
      rrp: '£105',
      ourPrice: '£55',
      salePrice: '£45',
      image: top
    },
    {
      title: 'POLO',
      typeOfcontent: 'Mens T-Shirt',
      rrp: '£105',
      ourPrice: '£55',
      salePrice: '£45',
      image: top
    },
    {
      title: 'POLO',
      typeOfcontent: 'Mens T-Shirt',
      rrp: '£105',
      ourPrice: '£55',
      salePrice: '£45',
      image: top
    },
    {
      title: 'POLO',
      typeOfcontent: 'Mens T-Shirt',
      rrp: '£105',
      ourPrice: '£55',
      salePrice: '£45',
      image: top
    },
    {
      title: 'POLO',
      typeOfcontent: 'Mens T-Shirt',
      rrp: '£105',
      ourPrice: '£55',
      salePrice: '£45',
      image: top
    },
    {
      title: 'POLO',
      typeOfcontent: 'Mens T-Shirt',
      rrp: '£105',
      ourPrice: '£55',
      salePrice: '£45',
      image: top
    }

  ]

  breakPoints = [
    { width: 2, itemsToShow: 2, itemsToScroll: 2 },
    { width: 550, itemsToShow: 3, itemsToScroll: 3},
    { width: 850, itemsToShow: 4, itemsToScroll: 3 },
    { width: 970, itemsToShow: 4, itemsToScroll: 3 },
    { width: 1150, itemsToShow: 5, itemsToScroll: 3 },
  ] 

  setDirection = (slideDirection) => {
    switch(slideDirection) {
      case "next":
        this.carousel.slideNext();
        let slideNext = document.getElementById('slider-move');
        
        if(slideNext.classList.contains('test-right')) {
          slideNext.classList.remove('test-right');
          slideNext.classList.add('test-left');
        }
            
      break;
      case "previous":
        this.carousel.slidePrev();
        let slidePrevious = document.getElementById('slider-move');
        
        if(slidePrevious.classList.contains('test-left')) {
          slidePrevious.classList.remove('test-left');
          slidePrevious.classList.add('test-right');
        }

      break;
    }
  }

  getAmountOfPages = (pages, activePage ) => {
  console.log(activePage)

  let firstItem = pages[0];
  let [lastItem] = pages.slice(-1);

  if(firstItem === activePage) {
    this.setState({
      leftArrow: false,
      rightArrow: true,
    })
  } else if(lastItem === activePage) {
    this.setState({
      leftArrow: true,
      rightArrow: false,
    })
  } else {
    this.setState({
      leftArrow: true,
      rightArrow: false,
    })
  }

// get first item in the array and compare it to the active page

// get the last element in the array and compare it to the active page
  }

  render() {
    return (
      <div className="content-slider-wrapper">
        <div className="content-slider-title">
          <span>PRODUCTS OF THE WEEK</span>
        </div>
        <div className={`${this.sliderData.length === 5 ? 'd-xl-none' : ''} arrow-container`}>
          <img onClick={() => this.setDirection("previous")} className="arrow-left" src={ArrowRight} />
          <img onClick={() => this.setDirection("next")} src={ArrowRight} />   
        </div>

        <div className={`${this.sliderData.length === 5 ? 'mt-xl-5' : ''} content-slider-container`}> 
        <div className="test-right" id="slider-move">
          
          
          <Carousel 
              ref={ref => (this.carousel = ref)}
              breakPoints={this.breakPoints} 
              disableArrowsOnEnd={true}
              renderPagination={({ pages, activePage, onClick }) => {
                this.getAmountOfPages(pages, activePage);
                return (
                  <div className={`${this.sliderData.length === 5 ? 'd-xl-none' : ''} black-slider-container`}>
                    {pages.map(page => {
                      const isActivePage = activePage === page
                      return (
                        <div className={isActivePage ? 'black-slider' : 'blank-slider'}
                          key={page}
                          onClick={() => onClick(page)}
                          active={isActivePage}
                        />
                      )
                    })}
                  </div>
                )
              }}
              >
              {this.sliderData.map((item, index) => (
                <div key={index} className="carousel-item-container">
                  <div className="carousel-image-container">
                    <img src={top} />
                  </div>
                  <div className="carousel-text-container">
                    <ul>
                      <li className="carousel-text-container-title">{item.title}</li>
                      <li className="carousel-text-container-text">{item.typeOfProduct}</li>
                      <li className="carousel-text-container-text line-through">RRP {item.rrp}</li>
                      <li className="carousel-text-container-text line-through">Our Price: {item.ourPrice}</li>
                      <li className="carousel-text-container-text">Sale Price: {item.salePrice}</li>
                    </ul>
                  </div>
                </div>
              ))}
            </Carousel>
          </div>
          </div>
      </div>
    )
  }
}

export default contentSlider;

我需要调用这个函数

this.getAmountOfPages(pages,activePage)

它在我的渲染中,可以在需要时更新状态,但是它没有任何想法.

EN

回答 1

Stack Overflow用户

发布于 2021-02-19 17:08:00

我是巴西人,所以我会说葡萄牙语,但是我会用翻译来帮助你。

通过以尝试的方式调用此函数,您将陷入无限循环。看:

  1. --您在render ()方法中更新状态;由于状态更新而调用
  2. -- render ()方法;
  3. --呈现方法更新状态;
  4. --再次重复

我已经使用过这个库了,所以我将向您展示我是如何做到的:

代码语言:javascript
复制
      <Carousel
          itemsToShow={7}
          renderArrow={renderArrow}
          enableMouseSwipe={false}
          pagination={false}
          breakPoints={[
            {
              width: 450,
              itemsToShow: 3,
              enableSwipe: true,
              enableMouseSwipe: true,
              itemsToScroll: 3,
              renderArrow: () => <div />,
            },
            {
              width: 500,
              itemsToShow: 3,
            },
            { width: 620, itemsToShow: 4 },
            { width: 720, itemsToShow: 5 },
            { width: 850, itemsToShow: 6 },
            { width: 1150, itemsToShow: 7 },
          ]}
        >
          {products &&
            products.map((p) => (
              <div key={p.docId} className="products-prod">
                <img
                  onClick={() => addProductCart(p)}
                  alt={p.descricao}
                  src={`data:image/png;base64,${p.thumbnail}`}
                  className={`shadow2 ${
                    !cart.includes(p.docId) && adding.includes(p.docId)
                      ? `pulse`
                      : ``
                  }`}
                />
                <section onClick={() => addProductCart(p)}>
                  {cart.includes(p.docId) ? (
                    <img src={ICONS.shoppingFilled} />
                  ) : (
                    <img src={ICONS.shoppingOutlined} />
                  )}
                </section>
                <article>
                  <h5>R$</h5>
                  {p.preco && formatCash(p.preco, true)}
                </article>
              </div>
            ))}
        </Carousel>

和:

代码语言:javascript
复制
  const renderArrow = ({ onClick, type, isEdge: noMoreItems }) => (
    <Button
      onClick={onClick}
      style={{
        margin: "auto 0",
        borderRadius: "100px",
        background: COLORS.primary,
        borderColor: COLORS.primary,
        width: "30px",
        minWidth: "30px",
        height: "30px",
        minHeight: "30px",
        padding: 0,
        display: "flex",
        justifyContent: "center",
        alignItems: "center",
      }}
      type="primary"
    >
      {type === consts.PREV ? (
        <CaretLeftOutlined style={{ margin: "2px 2px 0 0" }} />
      ) : (
        <CaretRightOutlined style={{ margin: "2px 0 0 2px" }} />
      )}
    </Button>
  );
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66281754

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档