Реагировать 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));
Другие вопросы по тегам