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

React组件注入服务遇this作用域问题,如何正确解决?

解决Cannot read property 'request' of undefined的作用域问题

你碰到的这个错误本质上是函数传递过程中this的上下文丢失导致的。当你把this.stringsService.bulk作为updater属性传给LocaleStringsList组件后,在子组件里调用this.props.updater时,这个函数的this已经不再指向LocaleStringsService的实例了,所以自然找不到this.api,就抛出了这个错误。

下面给你几种简单有效的解决方案:

方案1:在服务类的构造函数中绑定this

直接在LocaleStringsService的构造函数里,把bulk方法的this绑定到当前实例上,这样不管函数被传到哪里调用,this都能保持正确指向:

import React, { Component } from 'react';
import LocaleString from '../Entities/LocaleString.js';
import Api from '../Services/Api.js';

class LocaleStringsService extends Component {
  constructor (props) {
    super(props);
    this.api = new Api();
    // 关键:绑定bulk方法的this到实例
    this.bulk = this.bulk.bind(this);
  }

  bulk (locale, locales) {
    let data = [];
    // ...你的业务逻辑
    return this.api.request('PATCH', data, '/locales/' + locale + '/strings', {})
      .then(function (response) {
        console.log(response);
      });
  }
}

export default LocaleStringsService;

方案2:用箭头函数定义bulk方法

箭头函数会自动继承外层作用域的this,所以直接把bulk定义成箭头函数,就不用手动绑定了,代码更简洁:

import React, { Component } from 'react';
import LocaleString from '../Entities/LocaleString.js';
import Api from '../Services/Api.js';

class LocaleStringsService extends Component {
  constructor (props) {
    super(props);
    this.api = new Api();
  }

  // 用箭头函数定义方法,自动绑定this
  bulk = (locale, locales) => {
    let data = [];
    // ...你的业务逻辑
    return this.api.request('PATCH', data, '/locales/' + locale + '/strings', {})
      .then(function (response) {
        console.log(response);
      });
  }
}

export default LocaleStringsService;

方案3:传递props时用箭头函数包裹

如果你不想修改LocaleStringsService,也可以在父组件Translate传递updater的时候,用箭头函数包裹bulk的调用,确保调用时this指向正确的实例:

import React, { Component } from 'react';
import LocaleStringsService from '../Services/LocaleStringsService.js';
import LocaleStringsList from '../Components/LocaleStringsList.js';

class Translate extends Component {
  constructor(props) {
    super(props);
    this.state = { strings: [] }
    this.stringsService = new LocaleStringsService();
  }

  // ...其他业务逻辑

  render () {
    return (
      <LocaleStringsList 
        updater={(locale, strings) => this.stringsService.bulk(locale, strings)} 
        locale={this.props.match.params.locale}
        strings={this.state.strings} 
      />
    );
  }
}

export default Translate;

另外提个小建议:你的Api类其实不需要继承React.Component,它只是一个普通的服务类,修改一下会更规范(顺便修正你拼写的TESET为TEST):

import axios from 'axios';

class Api {
  constructor () {
    this.token = null;
    this.endpoint = process.env.REACT_APP_API_ENDPOINT;
    // 服务类不需要state,直接用实例属性即可
  }

  request (method, data, uri, headers) {
    uri = uri.replace(/^\//, '');
    return axios({
      method: method,
      url: `${this.endpoint}/${uri}`,
      data: data,
      headers: Object.assign({}, headers, { 
        Authorization: "Bearer TEST TOKEN"
      })
    });
  }
}

export default Api;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:43:25