繁体   English   中英

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

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

我是 React 的新手,过去 2 天一直在努力解决这个问题。 为什么当我把 this.imgList() 放在渲染中时调用它(不能存在 - 性能问题),但当它在 componentDidMount 中时不起作用?

所以我在构造函数中设置了状态:

class PersonalBananas extends React.Component {

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

然后在 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();
    }

我从我的 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
                });
            }
        });
    }

然后是这个臭名昭著的 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
        })
    };

在我的 render() 中,我尝试获取 IMAGES - 不起作用,但是当我将 {this.state.IMAGES} 替换为 {this.imgLis()} 并且在 imgLis() 中只返回 IMAGES 时它会起作用...


    render() {

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

export default PersonalBananas;

有什么帮助吗?

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

原因是this.imgList()使用this.state.images ,但是this.setState()在 React 中不是同步的。 由于render()在每个this.setState()之后调用,您的函数在那里工作,因为this.state.images已定义但未在componentDidMount()定义

componentDidMount() 运行一次,但其中有异步 API 调用 (axios)。 当在 componentDidMount() 中调用 this.imgList() 时,很可能您还没有得到回复。

简单的修复是

 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