在React组件中注入服务

时间:2018-05-14 13:24:06

标签: javascript reactjs

考虑以下情况:

import axios from 'axios';
import React, { Component } from 'react';

class Api
{
  constructor () {
    this.state = {
      token: null,
      endpoint: process.env.REACT_APP_API_ENDPOINT
    };
  }

  request (method, data, uri, headers) {
    uri = uri.replace(/^\//, '');

    return axios({
      method: method,
      url: this.state.endpoint + "/" + uri,
      data: data,
      headers: Object.assign({}, headers, { Authorization: "Bearer TESET TOKEN" })
    });
  }
}

export default Api; 
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={this.stringsService.bulk} locale={this.props.match.params.locale} strings={this.state.strings} />
      );
  }
}

export default Translate;
import React, { Component } from 'react';
import LocaleStringsListItem from './LocaleStringsListItem.js';

class LocaleStringsList extends Component {
  constructor (props) {
    super(props);

    [...]

    this.onSubmit = this.onSubmit.bind(this);

    [...]
  }

  onSubmit (e) {
    e.preventDefault();
    this.props.updater(this.props.locale, this.props.strings);
  }

  [...]

  render () {
    [...]

    return (
      <form onSubmit={that.onSubmit} [...]>
        [...]
      </form>
    );
  }
}

export default LocaleStringsList;
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 (locale, locales) {
    let data = [];

    [...]

    return this.api.request('PATCH', data, '/locales/' + locale + '/strings', {})
      .then(function (response) {
        console.log(response);
      });
  }
}

export default LocaleStringsService;

这是错误:

LocaleStringsService.js TypeError: Cannot read property 'request' of undefined

在传递函数时,this的范围和用法肯定存在一些问题。

我曾试图使用Context API但却失败了。

我该如何正确地做到这一点?

3 个答案:

答案 0 :(得分:1)

尝试使用类中的箭头函数语法(作为类属性的函数)

class LocaleStringsService extends Component
{
  // Attention to the syntax - Arrow Function as Class Property
  bulk = (locale, locales) => {
    //Todo
  }
}

export default LocaleStringsService;

参考:(在这里你会找到5种绑定this的方式。我已经向你展示了我个人喜欢的5号方式)https://medium.freecodecamp.org/react-binding-patterns-5-approaches-for-handling-this-92c651b5af56

答案 1 :(得分:1)

api字段未定义,因为this未绑定到您在bulk方法正文中所期望的值。尝试将其作为

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

答案 2 :(得分:-1)

我没有范围问题,但您不需要使用类对API模块进行建模。正常的功能可以 -

import axios from 'axios';

const token = null
const endpoint = process.env.REACT_APP_API_ENDPOINT

export function request(method, data, uri, headers) {
    uri = uri.replace(/^\//, '');

    return axios({
      method: method,
      url: endpoint + "/" + uri,
      data: data,
      headers: Object.assign({}, headers, { Authorization: "Bearer TESET TOKEN" })
    });
}

对模块进行更改有两个优点 -

  1. 使用请求函数的任何人都不需要创建API类的新实例
  2. 没有this范围问题。无论如何,这与此案无关。