Как сделать запрос axios, используя параметр маршрута из React Router, а затем обновить состояние на основе ответа?

У меня есть следующий маршрут в моем компоненте приложения:

<Route path ='/:id' component = {VideoPage} />

При посещении этого маршрута я хочу, чтобы компонент VideoPage использовал параметр :id для выполнения запроса axios к API, а затем я хочу обновить состояние VideoPage и отобразить информацию, которую возвращает API.

Это то, что я сейчас делаю в компоненте VideoPage, который не работает:

export default class VideoPage extends Component {

    constructor(props){
        super()
        this.state = {
            id: props.match.params.id,
            mainVideo: defaultVideo
        };
    }



    componentDidUpdate(){
        axios.get(getVideo(this.state.id))
            .then(res => {
                console.info(res)
                this.setState({
                    mainVideo: res.data
                })
            })
            .catch(err => console.info(err))
    }

    render() {
        // render several components, passing them pieces of state from this component
    }

Проблема в том, что когда я вызываю this.setState из componentDidUpdate, я получаю бесконечный цикл.

Итак, как бы вы это сделали (сделав вызов API, используя параметры из ReactRouter и )?

Что такое GetVedio?

Ragul CS 19.12.2020 07:32

getVideo — это просто функция, которая берет идентификатор и помещает его в строку.

Christopher Fotos 19.12.2020 07:53
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
2
990
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы должны проверить изменение состояния, которое вы хотите отслеживать, в componentDidUpdate, потому что в противном случае, когда вы вызываете setState в componentDidUpdate, это вызовет обновление и вызовет бесконечный цикл.

Я предполагаю, что вы хотите вызывать API каждый раз, когда изменяется состояние идентификатора. Вы можете использовать параметр prevState компонентаDidUpdate, перейдите по этой ссылке

Вы можете проверить состояние, сравнив prevState с текущим состоянием, как это

componentDidUpdate(prevProps, prevState) {
  if (this.state.id !== prevState.id) {
    axios.get(getVideo(this.state.id))
        .then(res => {
            console.info(res)
            this.setState({
                mainVideo: res.data
            })
        })
        .catch(err => console.info(err))
  }
}

Но componentDidUpdate вызывается после того, как произошло изменение, поэтому он не будет вызываться при первоначальном рендеринге, поэтому вам также нужно поместить вызов API в componentDidMount.

componentDidMount() {
  this.fetchVideo()
}

componentDidUpdate(prevProps, prevState) {
  if (this.state.id !== prevState.id) {
    this.fetchVideo()
  }
}

fetchVideo() {
  axios.get(getVideo(this.state.id))
        .then(res => {
            console.info(res)
            this.setState({
                mainVideo: res.data
            })
        })
        .catch(err => console.info(err))
}

Другие вопросы по теме