【问题标题】:Abstract client for <ApolloConsumer><ApolloConsumer> 的抽象客户端
【发布时间】:2018-12-24 03:07:56
【问题描述】:

我正在使用 Formik 来验证表单数据。作为附加验证,我检查数据库中是否存在用户电子邮件。我有这个代码工作,但我不喜欢它内联。有没有更好的方法来写这个,所以验证不必是内联的?我不明白如何让客户通过。

    <Form className="form">
            <ApolloConsumer>
                {client => (
                    <Field className="text-input" type="email" name="email" placeholder="Email" validate={async (value) => {
                        let error

                        const response = await client.query({
                            query: USER_EXISTS,
                            variables: {
                                query: value
                            }
                        })

                        console.log(response.data.userExists)

                        if (response.data.userExists) {
                            error = 'Email taken'
                        }

                        return error
                    }} />
                )}
            </ApolloConsumer>
      <Form>

例如,像这样:

<ApolloConsumer>
      {client => (
             <Field className="text-input" type="text" name="username" placeholder="Username" validate={this.validateUsername(client)} />
      )}
</ApolloConsumer>


validateUsername = async (value, client) => {
    let error

    const response = await client.query({
        query: USER_EXISTS,
        variables: {
            query: value
        }
    })

    console.log(response.data.userExists)

    if (response.data.userExists) {
        error = 'Username taken'
    }

    return error
}

【问题讨论】:

    标签: javascript apollo react-apollo formik


    【解决方案1】:

    您似乎需要一个 HOC(高阶组件)是一个返回组件的函数,因此要抽象您的函数,您需要类似

    const withApolloClient = (ConnectedComponent) => class extends React.Component {
      render() {
        return (
          <ApolloConsumer>
             {client => <ConnectedComponent {...this.props} client={client} />
          </ApolloConsumer>
        );
      }
    }
    

    一旦你设置了你的withApolloClient HOC,你就可以按如下方式使用它

    // create a field component with validation logic
    class FieldWithValidationApolloClient extends React.Component {
      async validateUsername() {
        let error;
        const { client, field } = this.props; // get apollo client injected by withApolloClient Hoc
        const { value } = field; // get value from the field
    
    
        const response = await client.query({
          query: USER_EXISTS,
          variables: {
            query: value
          }
        })
    
        console.log(response.data.userExists)
    
        if (response.data.userExists) {
          error = 'Username taken';
        }
    
        return error;
      }
    
      render() {
        return (
          <Field {...this.props} validate={this.validateUsername(client)} />
        );
      }
    }
    

    最后只是实现你的组件

    // import your withApolloClient component file
    import withApolloClient from './withApolloClient';
    import FieldWithApolloClient from './FieldWithValidationApolloClient';
    const FieldWithApollo = withApolloClient(FieldWithApolloClient);
    
    class YourFormComponent extends React.Component {
      render() {
        return (
          <form>
            <FieldWithApollo className="text-input" type="text" name="username" placeholder="Username" />
          </form>
        );
      }
    }
    <form>
    
    </form>
    

    记住{...this.props}会将所有声明的属性传播到标签组件中

    希望对你有帮助。

    【讨论】:

    • 谢谢!我还在熟悉 HOC,所以我会尝试实现它。
    猜你喜欢
    • 2020-05-27
    • 1970-01-01
    • 1970-01-01
    • 2019-12-25
    • 1970-01-01
    • 2016-05-16
    • 1970-01-01
    • 2017-05-31
    • 2011-12-18
    相关资源
    最近更新 更多