【问题标题】:ReactJS Component not updating on parent state changeReactJS 组件未在父状态更改时更新
【发布时间】:2020-01-30 12:12:31
【问题描述】:

我的 ReactJS 中有一个博客部分,它从无头 CMS 中提取帖子,页面使用分页并且一切正常,但是,在每个帖子项目中,我调用一个组件来输入作者姓名 > 所以基本上我拉一个来自 headless api 的 ID,我将其传递给组件并返回作者的姓名。

这在第一次运行良好,但每当我使用页面分页时,无论道具传递的信息如何,它都不会从组件中带回任何其他内容。这是我的代码;

博客页面;

getPosts(){
        if(this.state.posts.length){
            return this.state.posts.map((content,index) => {
                var url = content.Title.replace(/[^\w\s]/gi, '');
                url = url.replace(/\s+/g, '-').toLowerCase();
                    return(
                        <Col md={4} className="mb-4" key={index}>
                            
                            {({isVisible}) => 
                            <Card>
                                <Card.Body>
                                    <Link to={{ pathname: `/posts/${url}` }}>
                                        <Card.Title>{this.truncateOnWord(content.Title,50)}</Card.Title>
                                    </Link>
                                    <Card.Text>{this.truncateOnWord(content.SEOMetaDescription,150)}</Card.Text>
                                </Card.Body>
                                <Card.Footer>
                                    <PortraitTest displayFromAPIID={content.Author._id}></PortraitTest>
                                </Card.Footer>
                            </Card>
                            } 
                        </Col>
                    );
            })
        }
    }

handlePageClick = data => {
        var myElement = document.getElementById('articles');
        var topPos = myElement.offsetTop;
        window.scrollTo({top: topPos, behavior: 'smooth'});

        var selected = data.selected + 1;
        var offset = ((selected * this.state.perPage) - this.state.perPage);
        var limit = (this.state.perPage * selected);
    
        this.setState({ offset: offset, limit: limit }, () => {
          this.loadAPI();
        });
    };

render() {
        return (
            <div>
                        <CardDeck>
                            {this.getPosts()}
                        </CardDeck>

                        <ReactPaginate
                        previousLabel='&laquo;'
                        previousClassName={ 'previousBtn'}
                        nextLabel='&raquo;'
                        nextClassName={'nextBtn'}
                        breakLabel={'...'}
                        breakClassName={'break-me'}
                        activeClassName={'active'}
                        pageClassName={'page-item'}
                        pageLinkClassName={'page-link'}
                        containerClassName={'pagination'}
                        subContainerClassName={'pages pagination'}
                        pageCount={this.state.pageCount}
                        marginPagesDisplayed={2}
                        pageRangeDisplayed={5}
                        onPageChange={this.handlePageClick}
                    />
           </div>
        );
}

作者组件:

import React, { Component } from 'react';

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

        this.state = {
            displayFromAPIID: this.props.displayFromAPIID,
            name: null,
            apiID: null,
        }
        this.portraits = [
            { 
                'name': 'Name 1',
                'apiID': '5d84ba9c0a011064444a243e',
            },
            { 
                'name': 'Name 2',
                'apiID': '5d84bad40a011064444a2441',
            },
            { 
                'name': 'Name 3',
                'apiID': '5d84d4d00a011064444a244d',
            },
            { 
                'name': 'Name 4',
                'apiID': '5d84ba480a011064444a243a',
            },
            { 
                'name': 'Name 5',
                'apiID': '5d84d4900a011064444a244c',
            },
            { 
                'name': 'Name 6',
                'apiID': '5d84baeb0a011064444a2442',
            },
            { 
                'name': 'Name 7',
                'apiID': '5d84baaf0a011064444a243f',
            },
            { 
                'name': 'Name 8',
                'apiID': '5d84ba720a011064444a243c',
            },
            { 
                'name': 'Name 9',
                'apiID': '5d84d4120a011064444a244a',
            },
            { 
                'name': 'Name 10',
                'apiID': '5d84d4640a011064444a244b',
            },
            { 
                'name': 'Name 11',
                'apiID': '5d84b93a0a011064444a2439',
            },
            { 
                'name': 'Name 12',
                'apiID': '5d84d3b60a011064444a2449',
            },
            { 
                'name': 'Name 13',
                'apiID': '5d84bac00a011064444a2440',
            },
            { 
                'name': 'Name 14',
                'apiID': '5d84ba870a011064444a243d',
            },
            {
                'name': 'Name 15',
                'apiID': '5d84ba5e0a011064444a243b',
            },
            {
                'name': 'Name 16',
                'apiID': '5dd7cbf984b07d000dc63b2e',
            }
            ]
        
    }

    returnObj(){
        for (var i = 0; i < this.portraits.length; i++) {
            if(this.state.displayFromAPIID === Object.values(this.portraits[i])[1]){
                return(
                    <div>
                        <p><b>{Object.values(this.portraits[i])[0]}<br/>{Object.values(this.portraits[i])[1]}<br/>{this.props.displayFromAPIID}</b></p>
                    </div>
                )
            }
        }
    }
    
    render() {
        return (
            <div>
                {this.returnObj()}
            </div>
        );
    }
}

export default PortraitTest;

下面是组件输出到博客页面的截图。

有人知道我哪里出错了吗?

请注意,实际上博客文章所在的页面非常好,并且按预期工作,从 API 中提取正确的数据和分页工作完美,这是我请求信息的组件不起作用。

谢谢

【问题讨论】:

  • 您好,当您点击分页时,电话真的会发生吗?你检查过 devTool 的 Network&gt;XHR 部分吗?
  • 每次点击分页都会加载接下来的 9 个博客条目。这会从我们的 api 中提取正确的数据。您可以从屏幕截图中看到发送到组件的数据发生了变化(第 2 部分的第 2 个 ID 字符串),但该公司没有提供任何新内容

标签: reactjs react-props react-component


【解决方案1】:

那是因为构造函数在后续的渲染中没有被调用,它只被调用一次来初始化组件。要在属性更改时更新您的状态,您必须实现 componentDidUpdate。

componentDidUpdate(prevProps) {
  if (this.props.displayFromAPIID !== prevProps.displayFromAPIID) {
    this.setState({displayFromAPIID: this.props.displayFromAPIID});
  }
}

【讨论】:

  • 啊伙计,就是这样!!!我知道这与组件更新有关,但我无法加入这些点!谢谢!!!
猜你喜欢
  • 2021-06-08
  • 2017-12-03
  • 2017-06-06
  • 2019-12-23
  • 2016-10-02
  • 2019-01-16
  • 2018-08-14
  • 2018-07-08
  • 1970-01-01
相关资源
最近更新 更多