Apollo Client和Redux设置会导致无限渲染循环

问题描述 投票:0回答:1

我正在尝试将React Apollo与Redux连接起来,以便Apollo执行查询和突变,并将返回的数据分派到Redux商店,以便在应用程序周围分发数据。

我相信我已接近正确,但由于某种原因,该应用程序进入无限循环的Redux调度,我无法弄清楚为什么。

见下面的代码:

class Admin extends Component {
      constructor(props) {
        super(props);
      }

      render({
        adminAllTokens
      }, {}) {
        return ( /* JSX */  )
      );
    }
    }

    const AllRefreshTokens = gql `
      query {
        allUsers {
          refreshToken
          email
        }
      }
    `;

    const gqlWrapper = graphql(AllRefreshTokens, {
      props: ({
        ownProps,
        data
      }) => {
        ownProps.receivedAdminTokens(data.allUsers); //dispatch to Redux store
        return {
          ...data,
          gqladminAllTokens
        };
      }
    });

    function mapStateToProps(state, ownProps) {
      return {
        adminAllTokens: state.auth.adminAllTokens
      };
    }

    function mapDispatchToProps(dispatch) {
      return {
        receivedAdminTokens: tokens => {
          dispatch(adminTokensReceived(tokens));
        }
      };
    }

    const reduxWrapper = connect(mapStateToProps, mapDispatchToProps);
    export default compose(reduxWrapper, gqlWrapper)(Admin);

adminTokensReceived()操作位于reducer文件中:

export const adminTokensReceived = tokens => ({
    type: 'ADMIN_TOKENS_RECEIVED',
    tokens
});

GraphQL查询只发送一个网络请求,但控制台显示ADMIN_TOKENS_RECEIVED操作不断调度并崩溃浏览器。

提前致谢

redux infinite-loop react-apollo apollo-client
1个回答
1
投票

每当阿波罗HOC收到新的道具时,它会导致你的行动开火,这会更新商店并向你的Apollo HOC发送新的道具,这会导致你的行动开火......

有几种不同的方法可以解决这个问题。在我看来,最直接的方法是放弃graphql HOC并改用withApollo。就像是:

compose(
  withApollo,
  connect(mapStateToProps, mapDispatchToProps)
  lifecycle({
    componentDidMount() {
      const { client } = this.props
      client.query({ query: AllRefreshTokens })
        .then(({data}) => {
          receivedAdminTokens(data.allUsers)
        })
        .catch( //any error handling logic )
    }
  })
)

以上使用重构的lifecycle,但你可以很容易地将componentDidMount方法粘贴在组件中。

也就是说,当Apollo已经为您完成时,使用Redux存储GraphQL查询的结果似乎有点多余。

Apollo的默认行为是首先从缓存中检索数据,并且只在数据不存在时才发出网络请求(这也是您只看到一个网络调用的原因)。这意味着您的应用程序中的任何数量的组件都可以使用相同的graphql HOC进行包装,并且只有第一个要呈现的组件会触发对GraphQL端点的请求 - 所有其他组件都会从缓存中获取其data

© www.soinside.com 2019 - 2024. All rights reserved.