简体   繁体   English

React js - 在 render 中调用函数但在 componentDidMount 中没有

[英]React js - calling a function in render works BUT in componentDidMount doesn't

I'm new to React and have been struggling with this issue for the last 2 days.我是 React 的新手,过去 2 天一直在努力解决这个问题。 Why does the call to this.imgList() work when I put it in render (can't be there - performance issues), but doesn't when it's in componentDidMount?为什么当我把 this.imgList() 放在渲染中时调用它(不能存在 - 性能问题),但当它在 componentDidMount 中时不起作用?

So I set the state within the constructor:所以我在构造函数中设置了状态:

class PersonalBananas extends React.Component {

    constructor(){
        super();
        this.state = {
            username: 0,
            images: 0,
            pred: 0,
            IMAGES: 0
        }
    }

Then in componentDidMount I have two ajax calls which work and the call to imgLis() which doesn't:然后在 componentDidMount 中,我有两个有效的 ajax 调用和无效的 imgLis() 调用:



    componentDidMount() {
        axios.get('http://localhost:8081/auth/username')
            .then((response) => {
                let uname = response.data;
                this.setState({
                    username: uname
                });
            })

        axios.get('http://localhost:8081/auth/files')
            .then((response) => {
                let imgs = response.data;
                console.log("images response: "+imgs);
                this.setState({
                    images: imgs
                });
            })

        this.imgList();
    }

This method I call from my imgLis(), there are some ajax calls:我从我的 imgLis() 调用这个方法,有一些 ajax 调用:


    getImgPred = (path) => {
        var username = this.state.username;
        var $this = this;

        let regex = new RegExp(username+'\/(.*?)$');
        let imgRegex= /{username}\/(.*?)$/;

        let filename = regex.exec(path);
        console.log("filename at front:"+filename[1]);
        console.log("regex1:"+imgRegex+", regex2:"+regex);

        axios.post('http://localhost:8081/auth/imgpred',
            "filename=" + filename[1]
        ).then(function (response) {
            console.log("response at front (get img prediction):"+response.data);
            if (response.status === 200) {
                $this.setState({
                    pred: response.data
                });
            }
        });
    }

Then there is this infamous imgLis(), which works like a charm when I call it directly from render, but now doesn't:然后是这个臭名昭著的 imgLis(),当我直接从渲染中调用它时,它就像一个魅力,但现在没有:


    imgList = () => {
        var $this = this;
        const IMAGES = [];
        const imgpaths = this.state.images;

        for (let i = 0; i < imgpaths.length; i++) {
            var path = imgpaths[i]
            this.getImgPred(path);
            console.log("pred:"+$this.state.pred);

            IMAGES.push({
                src: process.env.PUBLIC_URL +`/${path}`,
                thumbnail: process.env.PUBLIC_URL +`/${path}`,
                thumbnailWidth: 320,
                thumbnailHeight: 320,
                caption: $this.state.pred
            })
        }
        this.setState({
            IMAGES: IMAGES
        })
    };

And in my render() I try to get the IMAGES -doesn't work, BUT it works when I replace {this.state.IMAGES} with {this.imgLis()} and in imgLis() just return IMAGES...在我的 render() 中,我尝试获取 IMAGES - 不起作用,但是当我将 {this.state.IMAGES} 替换为 {this.imgLis()} 并且在 imgLis() 中只返回 IMAGES 时它会起作用...


    render() {

        return (
            <div>
                <Gallery images={this.state.IMAGES}/>
            </div>
        )
    }
}

export default PersonalBananas;

Any help?有什么帮助吗?

In componentDidMount , use a callback function after this.setState like so:componentDidMount ,在this.setState之后使用回调函数, this.setState所示:

axios.get('http://localhost:8081/auth/files')
.then((response) => {
    let imgs = response.data;
    console.log("images response: "+imgs);
    this.setState({
      images: imgs
    }, () => {
      this.imgList();
    });
})

The reason being that this.imgList() uses this.state.images , but this.setState() is not synchronous in React.原因是this.imgList()使用this.state.images ,但是this.setState()在 React 中不是同步的。 Since render() is called after every this.setState() your function worked there, because this.state.images is defined but not in componentDidMount()由于render()在每个this.setState()之后调用,您的函数在那里工作,因为this.state.images已定义但未在componentDidMount()定义

componentDidMount() run once, but you have async API calls (axios) inside it. componentDidMount() 运行一次,但其中有异步 API 调用 (axios)。 When this.imgList() is called in componentDidMount(), most probably you had not get your response back yet.当在 componentDidMount() 中调用 this.imgList() 时,很可能您还没有得到回复。

Simple fix is简单的修复是

 axios('http://localhost:8081/auth/files') .then((response) => { let imgs = response.data; console.log("images response: "+imgs); this.setState( {images: imgs}, this.imgList // Will run after setState is completed ); })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM