React 组件循环更新 (GraphQL)

Posted

技术标签:

【中文标题】React 组件循环更新 (GraphQL)【英文标题】:React component loops updating (GraphQL) 【发布时间】:2018-06-07 04:55:02 【问题描述】:

美好的一天! 我不断得到

已超过最大更新深度。当组件在 componentWillUpdate 或 componentDidUpdate 中重复调用 setState 时,可能会发生这种情况。 React 限制了嵌套更新的数量以防止无限循环。

这看起来很明显,但我看不到组件中的循环。

ComponentWillUpdate() 表明它在短时间内调用了许多具有相同道具和状态的重新渲染。

提前致谢。

src/TitleList.js

class TitleList extends Component 
    constructor(props) 
        super(props)
        this.state = 'items': null
    
     onSortEnd = (oldIndex, newIndex) => 
        this.setState(
             items: arrayMove(this.state.items, oldIndex, newIndex),
         );
     ;
    render() 
        if (this.props.allTitlesQuery && this.props.allTitlesQuery.loading)
            return <div>Loading</div>
        
        if (this.props.allTitlesQuery && this.props.allTitlesQuery.error) 
            return <div>Error!</div>
        
        const titlesToRender = this.props.allTitlesQuery.allTitles
        this.setState('items': titlesToRender)
        return <SortableList
            items=this.state.items
            onSortEnd=this.onSortEnd
        />;
    

【问题讨论】:

【参考方案1】:

循环是由您的渲染函数中的this.setState('items': titlesToRender) 引起的

【讨论】:

【参考方案2】:

您不应该在渲染内部调用 setState,而是在另一个生命周期方法中调用,例如 componentDidMount 或 componentWillReceiveProps:

渲染不应修改状态:https://reactjs.org/docs/react-component.html#render

【讨论】:

【参考方案3】:

当您调用 this.setState 时,它​​会再次调用您的render。因此,如果您从渲染中调用 setState,它会进入递归循环。

你可以试试:-

class TitleList extends Component 
    constructor(props) 
        super(props)
        this.state = 'items': null
    
    componentDidMount () 
        this.updateState(props);
    

    componentWillReceiveProps (nextProps) 
        if (this.props.allTitlesQuery.allTitles !== nextProps.allTitlesQuery.allTitles) 
        this.setState(nextProps);
      
    

    updateState (props) 
        this.setState("items":props.allTitlesQuery.allTitles);
    

     onSortEnd = (oldIndex, newIndex) => 
        this.setState(
             items: arrayMove(this.state.items, oldIndex, newIndex),
         );
     ;
    render() 
        if (this.props.allTitlesQuery && this.props.allTitlesQuery.loading)
            return <div>Loading</div>
        
        if (this.props.allTitlesQuery && this.props.allTitlesQuery.error) 
            return <div>Error!</div>
        
        return <SortableList
            items=this.state.items
            onSortEnd=this.onSortEnd
        />;
    

第一次使用componentDidMount方法渲染数据,如果数据变化使用componentWillReceiveProps方法更新

【讨论】:

以上是关于React 组件循环更新 (GraphQL)的主要内容,如果未能解决你的问题,请参考以下文章

React Apollo:从组件状态动态更新 GraphQL 查询

如何在功能性 React JS 组件中获取数据?

使用 React TypeScript 进行 GraphQL 身份验证

如何使用 react-apollo graphql 确定突变加载状态

如何在 sangria-graphql 中执行突变?

在实用程序函数而不是组件中运行登录突变