javascript - 如何在 redux 操作中处理 XMLHttpRequest?

标签 javascript redux react-redux redux-form

我有一个 redux-form,它将 props 传递给我的 Action 。属性 this.props.userImages[0] 是来自该表单上输入的文件的图像文件。然后,我将获取该图像并向 Cloudinary 发送 XMLHttpRequest,后者会生成该图像的 url。一旦我收到 url 数据 (xhr.responseText),我想将其与其他 props 合并,然后我可以将所有 props 发布到 API(所有表单信息 + 新创建的图像 URL)。

我知道我必须等待我的请求才能生成要解决的网址,但在将其传递到其他函数之前遇到问题,该函数可以获取该信息并将其与 props 合并,然后再发布到我的API。

//..

function generateUrl(props) {

     // Grabs image file from my form's file input and uploads 
     // to cloudinary service so that a URL can be generated

  const cloudinaryURL = 'https://api.cloudinary.com/v1_1/<my_name>/image/upload';
  const apiKey = 'secret_key';
  const uploadPreset = 'test_preset';

  const data = new FormData();
  data.append('file', props.userImages[0]);
  data.append('upload_preset', uploadPreset);
  data.append('api_key', apiKey);

  const xhr = new XMLHttpRequest();
  xhr.open('POST', cloudinaryURL, true);
  xhr.send(data);
  xhr.onReadyStateChange = () => {
    if (xhr.readyState == 4 && xhr.status == 200) {
      return JSON.parse(xhr.responseText);
    }
  };

  return xhr.onReadyStateChange();
}

export function createReview(props) {

 const imageUrl = generateUrl(props);

 const mergedProps = //...

  // Here I'd like to merge my newly generated 
  // url back into props before I post to my API like so...

  const request = axios.post(`${REQUEST_URL}/api`, mergedProps)
  return {
    type: CREATE_REVIEW,
    payload: request
  }
};

非常感谢任何和所有帮助。

最佳答案

这与基于 XMLHttpRequest 的示例代码的上下文中的 promise 无关。

您所做的假设是分配给 onReadyStateChange 的回调对其返回值执行某些操作。相反,从该函数返回的任何内容都会被尽职地忽略。

您想要的是通过另一个回调传递该值。

function generateUrl(props, callback) {
  // Do things here
    xhr.onReadyStateChange = () => {
      if (xhr.readyState == 4 && xhr.status == 200) {
        callback(JSON.parse(xhr.responseText));
      }
    };
}


generateUrl(props, (response) => {
  const mergedProps = // Use response as expected.
});

既然您提到了 Promise 并使用了 ES2015,我们可以将其转换为实际使用的 Promise,这可能就是您想要开始的。

function generateUrl(props) {
  return new Promise((resolve, reject) => {
    const cloudinaryURL = 'https://api.cloudinary.com/v1_1/<my_name>/image/upload';
    const apiKey = 'secret_key';
    const uploadPreset = 'test_preset';

    const data = new FormData();
    data.append('file', props.userImages[0]);
    data.append('upload_preset', uploadPreset);
    data.append('api_key', apiKey);

    const xhr = new XMLHttpRequest();
    xhr.onReadyStateChange = () => {
      if (xhr.readyState == 4) {
        if (xhr.status == 200) {
          resolve(xhr.responseText);
        } else {
          reject(new Error(`Failed HTTP request (${xhr.status})`));
        }
    };
    xhr.onerror = reject;

    xhr.open('POST', cloudinaryURL, true);
    xhr.send(data);
  });
}

generateUrl(props)
  .then(JSON.parse)
  .then(results => {
    // Do something with response
  })
  .catch(error => {
    // Do something with the error
  });

关于javascript - 如何在 redux 操作中处理 XMLHttpRequest?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38557482/

相关文章:

javascript - ReactJS 当我使用 Redux 时所有组件都是类组件,这正常吗?

javascript - 如何使用 Jest 测试输出随机的函数?

javascript - 如何根据鼠标悬停在图像上的位置突出显示 gridview 行?

javascript - VueJS - v-if 和 v-show 无法正常工作

javascript - NVD3折线图单记录问题

reactjs - 如何在react redux中使用mapDispatchToProps

javascript - 在 onChange 事件中获取 redux-form 值

reactjs - 从不同的切片调用 reducer Redux Toolkit

javascript - Push 不是一个函数,Redux

javascript - React useSelector 先返回 undefined,再返回 object