简体   繁体   English

使用axios时如何停止javascript中的无限循环?

[英]How to stop an infinite loop in javascript when using axios?

I'm mapping through an array of items to generate images, but each time it sends my code into an infinite loop.我正在映射一组项目以生成图像,但每次都将我的代码发送到无限循环中。 Here's my code:这是我的代码:

This is the mapping code:这是映射代码:

let mySrc = this.state.imageUrl;

{myImages.map(image => {
       this.getSrc(userId, image.id); 

       return(
       <img src={mySrc}/>)
    })}

This is the "getSrc" function:这是“getSrc”函数:

getSrc = async (userId, image) => {
    axios
      .get(`http://mysiteeee.com/api/getimage/${userId}/photo/${image}`, {
           auth: {
              username: 'username',
              password: 'password'
              },
              responseType: 'blob'
            })
      .then(res => {
          let myUrl = URL.createObjectURL(res.data)
          console.log(myUrl)
          this.setState({
              imageUrl: myUrl
              })
      })
      .catch(err => console.log(err))
    } 

Whenever I go to the page, it shuffles through all the image URLs / images over and over forever.每当我访问该页面时,它都会一遍又一遍地遍历所有图像 URL/图像。 How do I only show the image URLs / images once?如何只显示一次图像 URL/图像? How do I stop shuffling through images infinitely?如何停止无限制地浏览图像?

Here's the entire component's code:这是整个组件的代码:

import React from 'react';
import axios from 'axios';

import HeaderTwo from './HeaderTwo';


class FullDescription extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            eventInfo: [],
            imageUrl: [],
            clicked: false,
        }
    }

    componentDidMount = () => {
        window.scrollTo(0,0);

        this.props.state.images.map(image => 
            this.getSrc(this.props.state.id, image.id))

        // this.getSrc(this.props.state.id, this.props.state.images[1].id)
    }

    changeClicked = (userId) => {
        if(this.state.clicked === false){
            this.setState({
                clicked: true
            }) 
        } else {
            this.setState({
                clicked: false
            })
        }
    }

    getSrc = async (userId, image) => {
        axios
            .get(`http://http://mysiteeee.com/api/getimage/${userId}/photo/${image}`, {
                auth: {
                    username: 'username',
                    password: 'password'
                    },
                    responseType: 'blob'
            })
            .then(res => {
                let myUrl = URL.createObjectURL(res.data)
                this.state.imageUrl.push(myUrl)

                // this.setState({
                //     imageUrl: myUrl
                //     })
            })
            .catch(err => console.log(err))
    } 

    render() {
        let item = this.props.state;
        let date = new Date(item.date).toDateString();
        let time = new Date(item.date).toLocaleTimeString();
        let userId = this.props.state.id;
        let myImages = this.state.imageUrl;
        let checkMark = <button className='attend-button' onClick={() => this.changeClicked(userId)}>Attend Event</button>;

        console.log(myImages)

        if(this.state.clicked === true){
            checkMark = <button className='attend-button' onClick={() => this.changeClicked(userId)}>&#x2713; Attend Event</button>
        } else {
            checkMark = <button className='attend-button' onClick={() => this.changeClicked(userId)}>Attend Event</button>
        }

        return(
            <div>
                <HeaderTwo/>
                <body id="full-description-page">
                <div className='images-section'>
                    {myImages.map(mySrc => <img src={mySrc}/>)}
                </div>
                    <div id='heading-strip'>
                        <img src={myImages} className='heading-image'/>
                        <div className='heading-info'>
                            <p className='date'>{date}<br/>{time}</p>
                            <p className='name'>{item.name}</p>
                            <p className='location'><b>Location:</b> <br/>{item.location.name}, {item.location.address}, {item.location.city}, {item.location.state}</p>
                            <div className='button-area'>
                                    {checkMark}
                                </div>
                        </div>
                    </div>

                    <br/>
                    <p className='description'><b>Description:</b> {item.description}</p>


                    <br/><br/><br/><br/>
                    <p className='comments-header'><b>Comments:</b></p>
                    <div className='comments-section'>
                        {item.comments.map(comment =>
                            <div className='comments'>
                                <p>{comment.text}<br/><b>-{comment.from}</b></p>
                            </div>
                        )}
                    </div>
                </body>
            </div>
        )
    }
}

export default FullDescription;

The issue in the code is that you are calling getSrc method inside the render method and updating the state .代码中的问题是您在 render 方法中调用getSrc方法并updating the state

Whenever there is a change in state, React will call the render method.每当状态发生变化时,React 都会调用 render 方法。

In this case React call the render method and in the render method there is a state update, hence React call the render method again, and this process goes on forever.在这种情况下,React 调用 render 方法,并且在 render 方法中有一个状态更新,因此 React 再次调用 render 方法,并且这个过程永远持续下去。

Solution.解决方案。

Remove the this.getSrc from render method and call the getSrc method in componentDidMount lifecycle hook.取出this.getSrc从渲染方法,并调用getSrc的方法componentDidMount生命周期挂钩。

I made a small change in the map function as well.我也对地图功能做了一些小改动。

Example.例子。

let myImages = this.state.imageUrl;

{myImages.map(mySrc => <img src={mySrc}/>)}

componentDidMount() {
 this.getSrc();
}

The fact that you are changing the state with :您正在通过以下方式更改状态的事实:

   this.setState({
      imageUrl: myUrl
   })

and at the same time you use this.state.imageUrl inside your render function, makes it loop continuously, because every time it renders, it starts again to do the array.map and the array.map call will trigger a new state update... so it loops forever.同时您在渲染函数中使用this.state.imageUrl ,使其连续循环,因为每次渲染时,它都会再次开始执行 array.map 并且 array.map 调用将触发新的状态更新。 ..所以它永远循环。

Also i think you might need to use map likke this另外我认为你可能需要使用像这样的地图

{myImages.map(image => {
   this.getSrc(image.userId, image.image.id); 

   return(
   <img src={mySrc}/>)
})}

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

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