状态正在更新,但是组件未将props中的更新状态发送给Reactjs中的子组件

时间:2019-05-11 18:10:19

标签: reactjs

我创建了4个组件,public static int twoToN(int n) { if(n<0){ throw new IllegalArgumentException("No negative values allowed"); } if(n==0){ return 1; }else{ return 2* twoToN(n-1); } } SalesBanner的父级。ProductImagePanelProductImagePanel的父级。并且ProductCarouselProgressbarProductCarouselProgressbar的父级。

所以就像

ProgressBar

我已经在 SalesBanner | v ProductImagePanel | v ProductCarouselProgressBar | v ProgressBar 组件中声明了状态,该组件作为道具被传递给了它的所有子组件。此外,我还在SalesBanner中定义了一个函数,该函数将更新状态,然后将更新后的状态发送回其子组件,因为在调用SalesBanner时将其重新呈现。 / p>

问题是,状态在setState()中正在更新,但没有传递(更新)到其子组件。

代码如下:

SalesBanner

class SaleBanner extends React.Component { constructor(props) { super(props); this.state = { numberOfProductsOnSale: 4, productCategories: [ ... ], productNames: [ ... ], productPrice: { oldPrice: [ ... ], salePrice: [ ... ] }, productImage: [ ... ], currentlyRenderedProductId: 1 //This is what i want to update } this.updateCurrentProductRenderedId = this.updateCurrentProductRenderedId.bind(this); } //This function will update the the state, and I want to pass its reference down to the child components updateCurrentProductRenderedId(newId) { this.setState(() => ({ currentlyRenderedProductId: newId })) } render() { return( <SalesBanner> <ProductDetails category={this.state.productCategories[this.state.currentlyRenderedProductId]} prodName={this.state.productNames[this.state.currentlyRenderedProductId]} prodOldPrice={this.state.productPrice.oldPrice[this.state.currentlyRenderedProductId]} prodSalePrice={this.state.productPrice.salePrice[this.state.currentlyRenderedProductId]} /> <ProductImagePanel updateState={this.updateCurrentProductRenderedId} numberOfProducts={this.state.numberOfProductsOnSale} currProductId={this.state.currentlyRenderedProductId} prodImage={this.state.productImage[this.state.currentlyRenderedProductId]}/> <ProductCarouselController /> </SalesBanner> ); } } 组件代码:

ProductImagePanel

class ProductImagePanel extends Component { constructor(props) { super(props); this.state = { numberOfProductsOnSale: props.numberOfProducts, currentlyRenderedProductId: props.currProductId, productImage: props.prodImage }; } render() { return ( <SaleProductImage> <ProductImageRendering /> <ProductCarouselProgressbar updateState={this.props.updateState} numberOfProducts={this.state.numberOfProductsOnSale} currProductId={this.state.currentlyRenderedProductId} prodImage={this.state.productImage}/> </SaleProductImage> ) } } 组件代码:

ProductCarouselProgressBar

class ProductCarouselProgressbar extends Component { constructor(props) { super(props); this.state = { numberOfProductsInSale: props.numberOfProducts, currentProductId: props.currProductId, productImage: props.prodImage }; } render() { return ( <ProductIdAndProgressPanel> <CurrentId> { this.state.currentProductId < 9 ? '0' + this.state.currentProductId : this.state.currentProductId } </CurrentId> <ProgressBar currentProdId={this.state.currentProductId} updateState={this.props.updateState} /> <TotalId> { this.state.numberOfProductsInSale < 9 ? '0' + this.state.numberOfProductsInSale : this.state.numberOfProductsInSale } </TotalId> </ProductIdAndProgressPanel> ) } } 组件代码:

ProgressBar

我没有解释的其他任何JSX语法都是React Component或styled-components标签。

2 个答案:

答案 0 :(得分:0)

当您将道具传递给子组件时,它不会直观地为您重新更新子组件的状态。如果要这样做,则需要使用componentDidUpdate()

class ProductImagePanel extends Component {
constructor(props) {
    super(props);

    this.state = {
        numberOfProductsOnSale: props.numberOfProducts,
        currentlyRenderedProductId: props.currProductId,
        productImage: props.prodImage
    };
}

componentDidUpdate(prevProps){
   if(prevProps.currProductId !== this.props.currProductId){
       this.setState({
            numberOfProductsInSale: this.props.numberOfProducts,
            currentlyRenderedProductId: this.props.currProductId,
            productImage: this.props.prodImage
       })
   }
}

render() {
    return (
        <SaleProductImage>
            <ProductImageRendering />
            <ProductCarouselProgressbar updateState={this.props.updateState} numberOfProducts={this.state.numberOfProductsOnSale} currProductId={this.state.currentlyRenderedProductId} prodImage={this.state.productImage}/>
        </SaleProductImage>
    )
}

}

答案 1 :(得分:0)

该值未更新,因为您正在将props值保存在每个组件的状态下,删除子组件内部的状态并直接从props访问这些值。

ProductImagePanel

class ProductImagePanel extends Component {

  render() {
    return (
      <SaleProductImage>
        <ProductImageRendering />
        <ProductCarouselProgressbar
          updateState={this.props.updateState}
          numberOfProducts={this.props.numberOfProducts}
          currProductId={this.props.currProductId}
          prodImage={this.props.productImage}
        />
      </SaleProductImage>
    );
  }
}

ProductCarouselProgressbar

class ProductCarouselProgressbar extends Component {
  render() {
    return (
      <ProductIdAndProgressPanel>
        <CurrentId>
          {' '}
          {this.props.currProductId < 9
            ? '0' + this.props.currProductId
            : this.props.currProductId}{' '}
        </CurrentId>
        <ProgressBar
          currentProdId={this.props.currProductId}
          updateState={this.props.updateState}
        />
        <TotalId>
          {' '}
          {this.props.numberOfProducts < 9
            ? '0' + this.props.numberOfProducts
            : this.props.numberOfProducts}{' '}
        </TotalId>
      </ProductIdAndProgressPanel>
    );
  }
}

ProgressBar

class ProgressBar extends Component {
  constructor(props) {
    super(props);
    this.progressBar = React.createRef();
  }

  componentDidMount() {
    setInterval(() => {
      this.progressBar.current.style['width'] =
        this.progressBar.current.offsetWidth + 1 + 'px';

      if (
        this.progressBar.current.offsetWidth >
        this.progressBar.current.parentNode.offsetWidth
      ) {
        this.progressBar.current.style['width'] = 0;
        this.props.updateState((this.props.currProductId % 4) + 1); //This is where I want to update state of the SalesBanner Component
      }
    }, 20);
  }

  render() {
    return (
      <OuterProgressBar>
        <InnerProgressBar ref={this.progressBar} />
      </OuterProgressBar>
    );
  }
}

Demo