<ApolloConsumer> 的抽象客户端
Abstract client for <ApolloConsumer>
我正在使用 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
}
您似乎需要一个 HOC(高阶组件)是一个 return 组件的函数,因此要抽象您的函数,您需要类似
的东西
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>
remember that {...this.props}
will spread all the attributes declare into the tag component
希望对您有所帮助。
我正在使用 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
}
您似乎需要一个 HOC(高阶组件)是一个 return 组件的函数,因此要抽象您的函数,您需要类似
的东西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>
remember that
{...this.props}
will spread all the attributes declare into the tag component
希望对您有所帮助。