【问题标题】:Passing components state to query variables inside react-apollo's compose将组件状态传递给 react-apollo 的 compose 中的查询变量
【发布时间】:2019-03-21 14:27:47
【问题描述】:

以下 React 组件可以正常工作,我可以使用 Apollo-React 查询 GraphQL 端点。在这种特定情况下,我使用 Apollo-React 的 compose 函数在同一个组件中添加多个查询。 我想在 HOC variables 字段中动态注入 userId。 有没有办法做到这一点?因为简单地调用函数getUser() 似乎不起作用,所以我只得到一个承诺。

  class AllCardsScreen extends Component {

    state = {
      query: '',
      userCardsById: [],
      userId:'',
      loading: false,
    };

    getUser = async () => {
    await Auth.currentUserInfo()
      .then((data) => {
        this.setState({ userId: data.attributes.sub});
      })
      .catch(error => console.log(`Error: ${error.message}`));
    };

  render() {

    return (
      <View style={styles.container}>
        <FlatList
          data={this.props.userCardsList}
          keyExtractor={this.keyExtractor}
          renderItem={this.renderItem}
          ItemSeparatorComponent={this.renderSeparator}
          ListHeaderComponent={this.renderHeader}
          keyboardShouldPersistTaps="handled"
        />
      </View>
    );
  }


 export default compose(

  graphql(ListCards, {
    options: (props) => ({
      fetchPolicy: 'cache-and-network',
      variables: { userId : '18e946df-d3de-49a8-98b3-8b6d74dfd652'}
    }),        
    props: (props) => ({
         userCardsList: props.data.userCardsList ? props.data.userCardsList.userCards : [],

    }),
  })

  )(AllCardsScreen);

编辑: 这也是基于 Daniel 建议 (Thx Daniel) 的最终工作版本,在 HOC Apollo-graphQl 增强器中注入了一个 API 异步调用。我必须调用data.props.refetch() 函数来更新variables 值。

 class AuthWrapper extends React.Component {

    state = {
      userId: null,
    }

    async componentDidMount () {
      const data = await Auth.currentUserInfo()
      this.setState({ userId: data.attributes.sub})
    }

    render () {
      return this.state.userId
        ? <AllCardsScreen {...this.state} {...this.props}/>
        : null
    }
  }


class AllCardsScreen extends Component {

    state = {
      query: '',
      userCardsById: [],
      userId:'',
      loading: false,
    };

  componentDidMount() {
    this.props.dataRefetch(this.props.userId)
    SplashScreen.hide();
  }

  render() {

    return (
      <View style={styles.container}>
        <FlatList
          data={this.props.userCardsList}
          keyExtractor={this.keyExtractor}
          renderItem={this.renderItem}
          ItemSeparatorComponent={this.renderSeparator}
          ListHeaderComponent={this.renderHeader}
          keyboardShouldPersistTaps="handled"
        />
      </View>
    );
  }


 export default compose(

  graphql(ListCards, {
    options: (props) => ({
      fetchPolicy: 'cache-and-network',
      variables: { userId : ''}
    }),        
    props: (props) => ({
    userCardsList: props.data.userCardsList ? props.data.userCardsList.userCards : [],
    dataRefetch: (userId) => {
        props.data.refetch({userId})
       },
    }),
  })

  )(AllCardsScreen);

【问题讨论】:

    标签: reactjs react-apollo


    【解决方案1】:

    graphql HOC 只使用道具——因为它实际上只是包装它传递的组件,所以它无法访问该组件的状态。也没有办法在 HOC 的配置中异步获取数据。

    最简单的解决方案是将状态提升到现有父组件或包装现有父组件的新组件中。例如:

    class WrapperComponent extends Component {
      state = {
        userId: null,
      }
    
      async componentDidMount () {
        const data = await Auth.currentUserInfo()
        this.setState({ userId: data.attributes.sub})
      }
    
      render () {
        // May want to render nothing or a loading indicator if userId is null
        return <AllCardsScreen userId={this.state.userId} {...otherProps} />
      }
    }
    

    或者,您可以创建自己的 HOC 来封装相同的逻辑:

    function authHOC(WrappedComponent) {
      return class AuthWrapper extends React.Component {
        state = {
          userId: null,
        }
    
        async componentDidMount () {
          const data = await Auth.currentUserInfo()
          this.setState({ userId: data.attributes.sub})
        }
    
        render () {
          return this.state.userId
            ? <WrappedComponent {...this.props} userId={this.state.userId} />
            : null
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-06-27
      • 2017-04-22
      • 2018-01-27
      • 2020-02-28
      • 2019-01-26
      • 2020-11-12
      • 2019-01-20
      • 2022-01-18
      • 1970-01-01
      相关资源
      最近更新 更多