为了账号安全,请及时绑定邮箱和手机立即绑定

在 componentDidUpdare 中 React setState 导致超出最大更新深度

在 componentDidUpdare 中 React setState 导致超出最大更新深度

慕仙森 2023-11-02 21:57:11
我正进入(状态错误:超出最大更新深度。当组件在 componentWillUpdate 或 componentDidUpdate 中重复调用 setState 时,可能会发生这种情况。React 限制嵌套更新的数量以防止无限循环。但我读到的内容应该能够在 componentDidMount 中调用 setState 而不会出现错误。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.log(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>)}}
查看完整描述

4 回答

?
弑天下

TA贡献1818条经验 获得超8个赞

发生这种情况是因为每个 setState 都会触发一次渲染,然后再次触发一次 componentDidMount,这基本上会导致无限循环。要停止该循环,您需要设置一些条件,以防止再次渲染,例如


    componentDidUpdate(previousProps, previousState) {

    if (previousProps.data !== this.props.data) {

        this.setState({/*....*/})

    }

   }


查看完整回答
反对 回复 2023-11-02
?
慕妹3242003

TA贡献1824条经验 获得超6个赞

我遇到了同样的错误。在使用效果方法中,我使用 axios 从后端获取数据并更新了状态。但在更新状态之前,我没有将 json 数据转换为状态的数据类型,这就是导致此错误的原因。


错误代码 :


Useeffect(() => {

    fetch

       .then((res) =>{

           setDate(res.data.date)

       }) 

})

正确代码:


Useeffect(() => {

    fetch

        .then((res) =>{

            setDate(new Date(res.data.date)) 

    }) 

}) 


查看完整回答
反对 回复 2023-11-02
?
红糖糍粑

TA贡献1815条经验 获得超6个赞

看来你想在 props 改变时改变状态来过滤一些产品。我删除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.log(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={...}/>

}


查看完整回答
反对 回复 2023-11-02
?
收到一只叮咚

TA贡献1821条经验 获得超4个赞

我认为你必须传递prevProps和/或prevState作为 的参数componentDidUpdate,并且仅当状态的 prop 或属性发生更改时才执行代码,


例子:


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


查看完整回答
反对 回复 2023-11-02
  • 4 回答
  • 0 关注
  • 134 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信