【问题标题】:State is updating, but the component is not sending updated state within the props to the child component in Reactjs状态正在更新,但组件没有将 props 中的更新状态发送到 Reactjs 中的子组件
【发布时间】:2019-09-29 06:35:07
【问题描述】:

我创建了 4 个组件,SalesBannerProductImagePanel 的父级。ProductImagePanelProductCarouselProgressbar 的父级。 ProductCarouselProgressbarProgressBar 的父级。

原来如此

     SalesBanner
          |
          v
  ProductImagePanel
          |
          v
ProductCarouselProgressBar
          |
          v
     ProgressBar

我在SalesBanner 组件中声明,它作为道具传递给它的所有子组件。此外,我还在SalesBanner 中定义了一个函数,它正在更新状态,然后将更新后的状态发送回其子组件,因为它们在调用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 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组件代码:

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.currentProdId % 4 )) + 1);    //This is where I want to update state of the SalesBanner Component
            }
        }, 20);
    }

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

我没有解释的任何其他 JSX 语法要么是 React 组件,要么是 styled-components 标签。

【问题讨论】:

  • 我想你在问它如何将状态值传播到顶层或父组件而不是向下传播?或者更确切地说从子组件更新父组件状态。
  • @Xixis。不,他已经能够使用他当前的代码来实现这一点。问题是他的子组件没有在父组件中使用更新的状态值重新渲染。
  • @S.乔希。刚刚为您写了一个答案,我认为它可以解决您问题的根源。如果您有任何问题,请告诉我。

标签: reactjs


【解决方案1】:

当您将道具传递给您的子组件时,它不会直观地为您重新更新子组件的状态。如果你想这样做,你需要使用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>
    )
}

}

【讨论】:

    【解决方案2】:

    该值没有更新,因为您将 props 值保存在每个组件的 state 中,删除子组件内的 state 并直接从 props 访问值。

    产品图像面板

    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>
        );
      }
    }
    

    进度条

    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

    【讨论】:

      猜你喜欢
      • 2017-11-05
      • 2021-08-26
      • 2021-07-21
      • 1970-01-01
      • 2022-10-15
      • 1970-01-01
      • 2019-08-31
      • 2019-03-10
      • 2021-06-08
      相关资源
      最近更新 更多