Реагировать js / superagent / файл dropzone
У меня есть виджет комментариев в React js (jsx), и я использую React Dropzone и загружаю удаленные файлы на сервер, используя суперагент.
Мне нужно получить объект файла (содержащий идентификатор файла моего приложения и т. Д.), Возвращенный из моего приложения, и связать их с комментарием, который отправит пользователь. Я пытаюсь присвоить объектам файла переменную состояния 'attachments'. Я думаю, что из-за асинхронной природы суперагента я на самом деле заполняю свою переменную состояния пустым массивом.
Я попытался использовать обратный вызов, но получил ошибку "undefined".
Вот код:
onDrop: function (newFiles) {
newFiles.forEach((file)=>
{
this.setState({files: this.state.files.concat(file)});
})
var attachments = [];
var req = request.post('/attachments/create');
req.set('Accept', 'application/json');
newFiles.forEach((file)=> {
req.attach('img_attach', file);
req.field('filename', file.name);
req.field('itemType', 'comment');
req.field('itemId', false);
req.end(function(err,res){
var json = $.parseJSON(res.text);
attachments.push(json);
attIds.push(json.id);
});
});
attachments.forEach((file)=>
{
this.setState({
attachments:this.state.attachments.concat([file])});
});
},
Вот попытка обратного вызова, которая возвращает "Не удается прочитать свойство 'setState' из неопределенного":
function fileAttach(err,res)
{
var json = $.parseJSON(res.text);
this.setState({attachments:this.state.attachments.concat([json])});
}
Для обратного вызова вместо этого
req.end(function(err,res){
var json = $.parseJSON(res.text);
attachments.push(json);
attIds.push(json.id);
});
Я использую это
req.end(fileAttach);
Итак, одна возможность состоит в том, что я ищу опцию "context", похожую на jquery, которая позволяет мне использовать "this" в обратном вызове.
1 ответ
Итак, вы были на правильном пути для первого выпуска, который я вижу. Вам нужно привязать контекст к этой функции. На это уже ответил LodeRunner28 в комментариях, но вы бы сделали:
req.end(fileAttach.bind(this))
Если вы не знакомы, Function.prototype.bind
позволяет вручную принудительно устанавливать переменную контекста для любой функции. Это невероятно удобно, и это означает, что вам никогда не придется полагаться на библиотеку (например, jQuery) для предоставления аргумента контекста, вы можете просто указать его самостоятельно:)
Большую проблему я вижу в том, как вы используете SuperAgent. Я полагаю, что вы на самом деле отправляете целую кучу запросов; призвание .end
запускает SuperAgent для выполнения запроса, и вы делаете это внутри цикла forEach.
Я не очень знаком с SuperAgent, но я верю, что вы можете просто сделать:
newFiles.forEach( file => {
req.attach('img_attach', file);
req.field('filename', file.name);
req.field('itemType', 'comment');
req.field('itemId', false);
});
req.end(fileAttach.bind(this));