Реакция setState внутри componentDidUpdare приводит к превышению максимальной глубины обновления

я осознаю

Ошибка: превышена максимальная глубина обновления. Это может произойти, когда компонент неоднократно вызывает setState внутри componentWillUpdate или componentDidUpdate. React ограничивает количество вложенных обновлений, чтобы предотвратить бесконечные циклы.

Но то, что я прочитал, должно вызывать setState внутри componentDidMount без ошибок.

class MyComponent extends Component {
constructor(props) {
    super(props);
    this.state = {
        matchtedProducts: [],
        products: [],
    }
}
async componentDidMount() {
    try {
        const products = await getProducts()
        this.setState({ products })
    } catch(err) {
        console.info(err)
    }
}

componentDidUpdate() {
    const productColor = this.props.size.trim().toLowerCase()
    const productSize = this.props.color.trim().toLowerCase()
    const matches = []

    this.state.products.map(product => {
        const title = product.title
        const titleSpliitet = title.split(',')

        let color = titleSpliitet[1].trim().toLowerCase()
        let size = titleSpliitet[2].trim().toLowerCase()

        if (color == productColor && size == productSize) {
            matches.push(product)
        }

    })
    this.setState({matchtedProducts: matches})
}
render() {
    return (<div></div>)
}

}

Поскольку, когда вы setState componentUpdates, когда компонент обновляется, он переходит в функцию componentDidUpdate и снова устанавливает состояние. Итак, существует бесконечный цикл. С другой стороны, componentDidMount срабатывает только один раз, в начале, поэтому он не приводит вас к бесконечному циклу, даже если вы устанавливаете состояние

Sinan Yaman 10.12.2020 15:25

почему вы обновляете состояние в componentDidUpdate?

Ali Faris 10.12.2020 15:26

Отвечает ли это на ваш вопрос? Использование ComponentDidUpdate и максимальная глубина обновления превышены

Sinan Yaman 10.12.2020 15:26
Поведение ключевого слова "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) для оценки ваших знаний,...
2
3
9 343
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Я думаю, вам нужно передать prevProps и/или prevState в качестве параметра (ов) componentDidUpdate и выполнить код, только если реквизит или свойство состояния изменилось,

Пример:

componentDidUpdate(prevProps, prevState) {
  // if the property count of the state has changed
  if (prevState.count !== this.state.count) {
    // then do your code
  }
}

Документы: https://en.reactjs.org/docs/react-component.html#componentdidupdate

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

class MyComponent extends Component {
constructor(props) {
    super(props);
    this.state = {
        matchtedProducts: [],
        products: [],
    }
}
async componentDidMount() {
    try {
        const products = await getProducts()
        this.setState({ products })
    } catch(err) {
        console.info(err)
    }
}

updateMatches = () => {

    const productColor = this.props.size.trim().toLowerCase()
    const productSize = this.props.color.trim().toLowerCase()
    const matches = []

    this.state.products.map(product => {
        const title = product.title
        const titleSpliitet = title.split(',')

        let color = titleSpliitet[1].trim().toLowerCase()
        let size = titleSpliitet[2].trim().toLowerCase()

        if (color == productColor && size == productSize) {
            matches.push(product)
        }

    })
    this.setState({matchtedProducts: matches})

}

render() {
    return (<div></div>)
}

}

и в родительском компоненте

changeSizeAndColor = () => {
     //note that I called updateMatches of MyComponent  
     this.setState({color : ... , size : ...} , () => this.myComponent.updateMatches());
}

render() { 
    return <MyComponent ref = {ref => this.myComponent = ref} color = {...} size = {...}/>
}
Ответ принят как подходящий

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

    componentDidUpdate(previousProps, previousState) {
    if (previousProps.data !== this.props.data) {
        this.setState({/*....*/})
    }
   }

Я получил ту же ошибку. В методе использования эффекта я извлек данные из бэкэнда с помощью axios и обновил состояния. Но перед обновлением состояний я не преобразовал данные json в тип данных состояния, поэтому это привело к этой ошибке.

Неверный код :

Useeffect(() => {
    fetch
       .then((res) =>{
           setDate(res.data.date)
       }) 
})

Правильный код:

Useeffect(() => {
    fetch
        .then((res) =>{
            setDate(new Date(res.data.date)) 
    }) 
}) 

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