React componentDidMount 获取 api

Posted

技术标签:

【中文标题】React componentDidMount 获取 api【英文标题】:React componentDidMount fetch api 【发布时间】:2019-04-17 12:13:30 【问题描述】:

我正在尝试在 componentDidMount 中获取 api。 api 结果将设置为组件的状态,并将状态映射并传递给子组件。

如果我使用里面的 fetch 方法获取 api,componentDidMount 一切正常:

componentDidMount()
    fetch(apiToFetch)
        .then((result) => result.json())
        .then((result) => result.entries)
        .then((entries) => this.setState( ...this.state, entries ))
        .catch((error) => console.log(error));

如果我在方法中使用 fetch,然后在 componentDidMount 中调用此方法,则不会呈现任何内容:

componentDidMount() 
    this.fetchApiToEntries(GLOBAL_PORTFOLIO_COLLECTION_API);


fetchApiToEntries(apiToFetch) 
    fetch(apiToFetch)
        .then((result) => result.json())
        .then((result) => result.entries)
        .then((entries) => this.setState( ...this.state, entries ))
        .catch((error) => console.log(error));

我无法理解我在生命周期中缺少什么。 不应该做出以下反应吗?

初始化状态 渲染 调用componentDidMount 重新渲染

这是我的初始组件:

export default class Portfolio extends React.Component 
    constructor(props) 
        super(props);
        this.state = 
            entries: []
        

    
    componentDidMount() 

        this.fetchApiToEntries(GLOBAL_PORTFOLIO_COLLECTION_API);
    
    fetchApiToEntries(apiToFetch) 
        fetch(apiToFetch)
            .then((result) => result.json())
            .then((result) => result.entries)
            .then((entries) => 
                this.setState(
                    ...this.state,
                    entries
                )
            )
            .catch((error) => console.log(error));
    

    render() 

        return (
            <Fade bottom>
                <div className="Portfolio">
                    <div className="Portfolio__title"><h4 className="color--gradient text--spacing">WORKS</h4></div>
                    <OwlCarousel ...options>
                        this.state.entries.map((item) => (
                            <PortfolioElement item=item />
                        ))
                    </OwlCarousel>
                    <AnchorLink href='#contact'><Button className="contact-button btn--gradient slider-button Services__button">Let's get in touch</Button></AnchorLink>
                </div>
            </Fade>
        )
    

PortfolioElement 是未呈现的实际组件。 有什么建议吗? 谢谢。

编辑: 两种方法都没有以正确的方式重新渲染组件(......我没想到的事情:我不知道为什么,但如果我在 componentDidMount 中调用它们两次,组件将以正确的方式渲染)。我想我在该州缺少一些东西。

我在控制台中没有错误,这就是我设置初始状态的方式:

this.state=entries:[]

这就是控制台中实际条目的样子:

 entries:
[0:credits: "..."
    description: "..."
    featuredImage: path: "portfolio/01.jpg"
    firstImage: path: "portfolio/firstimage.jpg"
    secondImage: []
    slug: "..."
    tasks: (5) […, …, …, …, …]
    title: "..."
    _by: "5beae6553362340b040001ee"
    _created: 1542123322
    _id: "5beaef3a3362340bf70000b4"
    _mby: "5beae6553362340b040001ee"
    _modified: 1542149308
,
1:...
]

获取后我的状态是一样的。

更新我发现问题是:当状态改变时,组件没有用正确的道具重新渲染孩子。我在传递 props 的高阶组件中调用 API,并添加了一个 componentWillUpdate 方法,强制刷新状态以重新渲染组件。不是理想的解决方案,但直到现在我才想出其他方法。有什么建议吗?

【问题讨论】:

我知道构造函数中的方法绑定丢失了。 不应该做出以下反应吗? - 应该。 如果我在方法中使用 fetch,然后在 componentDidMount 中调用该方法,则不会呈现任何内容 - 这不太可能。这两个componentDidMount sn-ps 的行为应该完全相同,只要apiToFetch 相同。考虑提供一种方法来复制问题。 它应该可以工作,请检查控制台日志是否有任何错误或将其复制到 codepen 以便其他人调试问题 你能做一个日志,给我们看看result.entries的结构吗?您是否在控制台、网络或浏览器中遇到错误? 我没有收到任何错误,我必须编辑我的问题:两种方法都给出相同的结果。我想我在初始状态下遗漏了一些东西。我会更新问题。 【参考方案1】:

知道你的 api 响应是什么,但我用假 API 测试了你的代码并更改了

fetchApiToEntries(apiToFetch)

到箭头函数 (Arrow Function)

fetchApiToEntries = (apiToFetch) => 

它工作正常。

完整示例:



    export default class Portfolio extends React.Component 
        constructor(props) 
            super(props);
            this.state = 
                entries: []
            
        
        componentDidMount() 
          this.fetchApiToEntries('https://jsonplaceholder.typicode.com/posts');
        
        fetchApiToEntries = (apiToFetch) => 
            fetch(apiToFetch)
                .then(result => result.json())
                .then((entries) => 
                    this.setState(
                        ...this.state,
                        entries
                    )
                )
                .catch((error) => console.log(error));
        
        render() 
          const entries = this.state;
            console.log(entries);
            return (
                // Everything you want to render.
            )
        
    

希望对你有帮助。

【讨论】:

这段代码没有箭头也可以工作,所以这里不需要。 谢谢,但我之前也尝试过,没有任何变化,我已经在问题编辑中发布了 api 响应。顺便说一句,将状态映射到一个简单的 而不是子组件内部可以正常工作。想知道我是否必须在更高阶的组件中设置状态并将状态作为道具传递,即使我觉得没有必要。【参考方案2】:

需要在构造函数中绑定fetchApiToEntries还是使用粗箭头?

this.fetchApiToEntries = this.fetchApiToEntries.bind(this);

对不起,我不能评论没有足够的代表

【讨论】:

不,你不需要。 正如我的评论中所述,我知道它丢失了,但在这种情况下它不相关...... 断点设置状态的位并检查其中的内容。因为它在 fetch 和 setState 之后一直绑定(使用粗箭头)将触发重新渲染。我猜这不是你想要的。

以上是关于React componentDidMount 获取 api的主要内容,如果未能解决你的问题,请参考以下文章

React componentDidMount

async/await 不适用于 ComponentDidMount 中的 react.js

text #react #componentDidMount

React componentDidMount“解析错误:缺少分号”

Apollo + React:数据未出现在 componentDidMount 生命周期中

React componentDidMount() 初始化状态