Promise isn't working in react component when

2019-07-25 04:37发布

问题:

Good day. I have the following problem: I have an item editor. How it works: I push 'Add' button, fill some information, click 'Save' button. _onSaveClicked function in my react component handles click event and call function from service, which sends params from edit form to server and return promise. _onSaveClicked implements

.then(response => {
    console.log('I\'m in then() block.');
    console.log('response', response.data);
}) 

function and waits for promise result. It works in real situation. I created fake service and placed it instead of real service. Service's function contains:

return Promise.resolve({data: 'test response'});

As you can see fake service return resolved promise and .then() block should work immediatly. But .then() block never works.

Jest test:

jest.autoMockOff();

const React = require('react');
const ReactDOM = require('react-dom');
const TestUtils = require('react-addons-test-utils');
const expect = require('expect');
const TestService = require('./service/TestService ').default;


let testService = new TestService ();

describe('TestComponent', () => {
  it('correct test component', () => {
    //... some initial code here
    let saveButton = TestUtils.findRenderedDOMComponentWithClass(editForm, 'btn-primary');
    TestUtils.Simulate.click(saveButton);
    // here I should see response in my console, but I don't
  });
});

React component save function:

 _onSaveClicked = (data) => {
    this.context.testService.saveData(data)
      .then(response => {
        console.log('I\'m in then() block.');
        console.log('response', response.data);
      });
  };

Service:

export default class TestService {
  saveData = (data) => {
    console.log('I\'m in services saveData function');
    return Promise.resolve({data: data});
  };
}

I see only "I'm in services saveData function" in my console.

How to make it works? I need to immitate server response.

Thank you for your time.

回答1:

You can wrap your testing component in another one like:

class ContextInitContainer extends React.Component {

  static childContextTypes = {
    testService: React.PropTypes.object
  };

  getChildContext = () => {
    return {
      testService: {
        saveData: (data) => {
          return {
            then: function(callback) {
              return callback({
                // here should be your response body object
              })
            }
          }
        }
      }
    };
  };

  render() {
    return this.props.children;
  }
}

then:

<ContextInitContainer>
  <YourTestingComponent />
</ContextInitContainer>

So your promise will be executed immediately.