代码之家  ›  专栏  ›  技术社区  ›  Cris69

将组件状态传递给react apollo的compose中的查询变量

  •  1
  • Cris69  · 技术社区  · 6 年前

    下面的React组件工作正常,我能够使用Apollo React查询GraphQL端点。在这种情况下,我用的是阿波罗反应器 compose 我想在HOC中动态注入 variables 字段,用户ID。 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);
    

    编辑: data.props.refetch() 函数来更新 变量 价值观。

     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);
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Daniel Rearden    6 年前

    这个 graphql HOC只使用props——因为它实际上只是包装它所传递的组件,所以它不能访问该组件的状态。在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} />
      }
    }
    

    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
        }
      }
    }