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

我正进入(状态

错误:超出最大更新深度。当组件在 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>)

}

}


慕仙森
浏览 136回答 4
4回答

弑天下

发生这种情况是因为每个 setState 都会触发一次渲染,然后再次触发一次 componentDidMount,这基本上会导致无限循环。要停止该循环,您需要设置一些条件,以防止再次渲染,例如&nbsp; &nbsp; componentDidUpdate(previousProps, previousState) {&nbsp; &nbsp; if (previousProps.data !== this.props.data) {&nbsp; &nbsp; &nbsp; &nbsp; this.setState({/*....*/})&nbsp; &nbsp; }&nbsp; &nbsp;}

慕妹3242003

我遇到了同样的错误。在使用效果方法中,我使用 axios 从后端获取数据并更新了状态。但在更新状态之前,我没有将 json 数据转换为状态的数据类型,这就是导致此错误的原因。错误代码 :Useeffect(() => {&nbsp; &nbsp; fetch&nbsp; &nbsp; &nbsp; &nbsp;.then((res) =>{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;setDate(res.data.date)&nbsp; &nbsp; &nbsp; &nbsp;})&nbsp;})正确代码:Useeffect(() => {&nbsp; &nbsp; fetch&nbsp; &nbsp; &nbsp; &nbsp; .then((res) =>{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; setDate(new Date(res.data.date))&nbsp;&nbsp; &nbsp; })&nbsp;})&nbsp;

红糖糍粑

看来你想在 props 改变时改变状态来过滤一些产品。我删除componentDidUpdate代码并在组件中添加一个方法来进行过滤,然后我将从父组件中调用该方法class MyComponent extends Component {constructor(props) {&nbsp; &nbsp; super(props);&nbsp; &nbsp; this.state = {&nbsp; &nbsp; &nbsp; &nbsp; matchtedProducts: [],&nbsp; &nbsp; &nbsp; &nbsp; products: [],&nbsp; &nbsp; }}async componentDidMount() {&nbsp; &nbsp; try {&nbsp; &nbsp; &nbsp; &nbsp; const products = await getProducts()&nbsp; &nbsp; &nbsp; &nbsp; this.setState({ products })&nbsp; &nbsp; } catch(err) {&nbsp; &nbsp; &nbsp; &nbsp; console.log(err)&nbsp; &nbsp; }}updateMatches = () => {&nbsp; &nbsp; const productColor = this.props.size.trim().toLowerCase()&nbsp; &nbsp; const productSize = this.props.color.trim().toLowerCase()&nbsp; &nbsp; const matches = []&nbsp; &nbsp; this.state.products.map(product => {&nbsp; &nbsp; &nbsp; &nbsp; const title = product.title&nbsp; &nbsp; &nbsp; &nbsp; const titleSpliitet = title.split(',')&nbsp; &nbsp; &nbsp; &nbsp; let color = titleSpliitet[1].trim().toLowerCase()&nbsp; &nbsp; &nbsp; &nbsp; let size = titleSpliitet[2].trim().toLowerCase()&nbsp; &nbsp; &nbsp; &nbsp; if(color == productColor && size == productSize) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; matches.push(product)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; })&nbsp; &nbsp; this.setState({matchtedProducts: matches})}render() {&nbsp; &nbsp; return (<div></div>)}}并在父组件中changeSizeAndColor = () => {&nbsp; &nbsp; &nbsp;//note that I called updateMatches of MyComponent&nbsp;&nbsp;&nbsp; &nbsp; &nbsp;this.setState({color : ... , size : ...} , () => this.myComponent.updateMatches());}render() {&nbsp;&nbsp; &nbsp; return <MyComponent ref={ref => this.myComponent = ref} color={...} size={...}/>}

收到一只叮咚

我认为你必须传递prevProps和/或prevState作为 的参数componentDidUpdate,并且仅当状态的 prop 或属性发生更改时才执行代码,例子:componentDidUpdate(prevProps, prevState) {&nbsp; // if the property count of the state has changed&nbsp; if (prevState.count !== this.state.count) {&nbsp; &nbsp; // then do your code&nbsp; }}文档:https ://en.reactjs.org/docs/react-component.html#componentdidupdate
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript