You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在TypeScript+Apollo中为React类组件添加类型化SignIn Mutation方法

使用react-apollo为React类组件添加类型化的signIn方法

针对你的需求,我整理了完整的实现方案,包含TypeScript类型化版本和JavaScript简化版本,方便你根据项目情况选择:

TypeScript类型化实现(推荐)

如果你的项目用TypeScript,我们可以通过定义明确的类型来让signIn方法获得完整的类型提示和校验:

import React from 'react';
import SignInMutation from '~/mutations/SignInMutation.gql';
import { graphql, MutationFunc } from 'react-apollo';

// 定义登录需要的变量类型
interface SignInVariables {
  email: string;
  password: string;
}

// 定义Mutation返回的数据结构类型
interface SignInResponse {
  signIn: {
    token: {
      accessToken: string;
      accessTokenExpiresOn: string;
    };
  };
}

// 定义组件接收的props类型
interface SignInComponentProps {
  signIn: (variables: SignInVariables) => Promise<SignInResponse>;
}

class SignInComponent extends React.Component<SignInComponentProps> {
  handleLogin = async (email: string, password: string) => {
    try {
      const loginResult = await this.props.signIn({ email, password });
      // 登录成功后的逻辑,比如存储token到本地
      localStorage.setItem('authToken', loginResult.signIn.token.accessToken);
      console.log('登录成功,token有效期:', loginResult.signIn.token.accessTokenExpiresOn);
    } catch (error) {
      // 处理登录失败,比如提示用户账号密码错误
      alert(`登录失败: ${error.message}`);
    }
  };

  render() {
    return (
      <div className="login-form">
        {/* 这里可以添加邮箱密码输入框,绑定到state后调用handleLogin */}
        <button onClick={() => this.handleLogin('user@example.com', '123456')}>
          登录
        </button>
      </div>
    );
  }
}

// 用graphql高阶组件包装组件,映射出类型化的signIn方法
export default graphql(SignInMutation, {
  props: ({ mutate }: { mutate: MutationFunc<SignInResponse, SignInVariables> }) => ({
    signIn: async (variables: SignInVariables) => {
      const response = await mutate({ variables });
      // 额外判断返回数据是否存在,避免空值问题
      if (!response.data) {
        throw new Error('登录请求未返回有效数据');
      }
      return response.data;
    },
  }),
})(SignInComponent);

JavaScript简化实现

如果你的项目用纯JavaScript,可以去掉类型定义部分,简化代码:

import React from 'react';
import SignInMutation from '~/mutations/SignInMutation.gql';
import { graphql } from 'react-apollo';

class SignInComponent extends React.Component {
  handleLogin = async (email, password) => {
    try {
      const loginResult = await this.props.signIn({ email, password });
      localStorage.setItem('authToken', loginResult.signIn.token.accessToken);
      console.log('登录成功');
    } catch (error) {
      alert(`登录失败: ${error.message}`);
    }
  };

  render() {
    return (
      <div className="login-form">
        <button onClick={() => this.handleLogin('user@example.com', '123456')}>
          登录
        </button>
      </div>
    );
  }
}

export default graphql(SignInMutation, {
  props: ({ mutate }) => ({
    signIn: (variables) => mutate({ variables })
      .then(response => {
        if (!response.data) throw new Error('无返回数据');
        return response.data;
      }),
  }),
})(SignInComponent);

关键细节说明

  • props映射逻辑:在graphql的第二个参数中,我们通过props函数把原生的mutate方法包装成业务友好的signIn方法,直接接收登录所需的邮箱和密码变量。
  • 错误处理:在包装后的signIn方法里,我们做了额外的空值检查,避免后续操作出现未定义错误,同时统一抛出错误让组件层面处理。
  • 装饰器语法:如果你习惯用装饰器(比如@graphql(...)),只要你的项目编译环境支持(比如TypeScript开启experimentalDecorators,或Babel配置装饰器插件),可以把HOC包装改成装饰器形式:
@graphql(SignInMutation, {
  props: ({ mutate }: { mutate: MutationFunc<SignInResponse, SignInVariables> }) => ({
    signIn: async (variables: SignInVariables) => {
      // 同上的signIn逻辑
    },
  }),
})
class SignInComponent extends React.Component<SignInComponentProps> {
  // 组件内容
}

内容的提问来源于stack exchange,提问作者lifeiscontent

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:29:39