如何在 redux 操作中处理 XMLHttpRequests?
How to handle XMLHttpRequests in a redux action?
我有一个 redux-form 正在将 props 传递给我的 action。 属性 this.props.userImages[0] 是来自该表单上输入的文件的图像文件。然后,我将拍摄该图像并制作 XMLHttpRequest 到 Cloudinary,后者为该图像生成 url。一旦我收到 url 数据 (xhr.responseText),我想将它与我的其他道具合并,然后我可以 post 我所有的道具到 API(所有表单信息 + 新创建的图像 URL)。
我知道我必须等待我的请求生成一个 url 来解决,但是在我将它传递到我的其他函数之前遇到了问题,它可以获取该信息并合并它在 post 进入我的 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
的示例代码上下文中的承诺无关。
您所做的假设是分配给 onReadyStateChange
的回调对其 return 值执行某些操作。相反,从该函数 return 编辑的任何内容都将被尽职地忽略。
你想要的是通过另一个回调向前传递值。
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,我们可以将其转换为实际使用 promises,这可能正是您想要开始的。
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
});
我有一个 redux-form 正在将 props 传递给我的 action。 属性 this.props.userImages[0] 是来自该表单上输入的文件的图像文件。然后,我将拍摄该图像并制作 XMLHttpRequest 到 Cloudinary,后者为该图像生成 url。一旦我收到 url 数据 (xhr.responseText),我想将它与我的其他道具合并,然后我可以 post 我所有的道具到 API(所有表单信息 + 新创建的图像 URL)。
我知道我必须等待我的请求生成一个 url 来解决,但是在我将它传递到我的其他函数之前遇到了问题,它可以获取该信息并合并它在 post 进入我的 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
的示例代码上下文中的承诺无关。
您所做的假设是分配给 onReadyStateChange
的回调对其 return 值执行某些操作。相反,从该函数 return 编辑的任何内容都将被尽职地忽略。
你想要的是通过另一个回调向前传递值。
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,我们可以将其转换为实际使用 promises,这可能正是您想要开始的。
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
});