处理输入文件中的文件并稍后上传以响应redux

时间:2018-07-10 18:19:40

标签: reactjs redux

我是一个非常新的反应者,我需要(直到)找到一个解决方案,但是并不能解决这个问题!

因此,就目前而言,我在我的react应用程序中某处有文件输入,可以在其中放置jpg文件,而在其他文件中可以放置pdf文件。这里没什么疯狂的。但是我需要处理这些文件,以便稍后再上传,因为它就像一个多页表单……我尝试了很多事情,但找不到有效的文件。

基于Store Input File Selected in Redux to Upload Later,该解决方案看起来太简单了,也无法正常工作...

我试图在redux存储中处理文件(blob路径,文件对象,文件路径...),但是没有任何反应。顺便说一句,邮递员的要求运作良好,我可以用它上传文件。

这是我做的一些代码,目前无法正常工作(已发送请求,但数据库中文件路径仍为NULL)。我正在使用Symfony3作为后端。存储中的其他数据在我的数据库中传递,只有文件没有传递。

我的输入之一:

<input 
      type="file" 
      className="input-file" 
      name="flyer-pdf" 
      id="flyer-pdf"
      onChange={this.handleChangeFilePath('flyer')} 
      accept=".pdf"
/>

我更新状态的方法:

handleChangeFilePath = prop => (event) => {
    this.setState({
        // Tried event.target.files[0]
        [prop]: event.target.value,
    });
};

提交表格:

handleSubmit = (logo, flyer) => {
   this.props.flyerSetup(logo, flyer);
};

调用方法的方法:

const mapDispatchToProps = (dispatch) => {
    return {
        flyerSetup: (logo, flyer) => dispatch(appActions.flyerSetup(logo, flyer))
    };
};

被叫动作:

export const flyerSetup = (logo, flyer) => ({
    type: types.CLIENT_FLYER_SETUP,
    logo: logo,
    flyer: flyer
});

在appReducer中调用操作以更新Redux存储:

case types.CLIENT_FLYER_SETUP:
        return {
            ...state,
            logo: action.logo,
            flyer: action.flyer
        };

这是我的动作:

export const createTransaction = () => (getState) => {
const state = getState();
const data = {
    logo: state.appReducer.logo,
    flyer: state.appReducer.flyer
}
console.log(data);
return transactionService.postTransaction(data)

console.log(data)很好,我的商店已经很好地更新了我从输入中提供的数据,我总是得到blob路径/文件路径/文件对象,但是正如我所说,我无法将文件上传到我的服务器中:(

P.s:我修改并清除了代码以使其更具可读性,请随时要求更多;)

1 个答案:

答案 0 :(得分:0)

找到了一种解决方法,最初没有意识到我正在使用超级代理(自开始以来我就不在该项目上),我的问题不是File对象存储方法,而是我在http请求中的标头:

static headers (headers = {}) {
    return Object.assign({
        // The application/json header was forced at every request
        // "Content-Type": "application/json",
        "Cache-Control": "no-cache",
        "Pragma": "no-cache",
        "Expires": "-1",
        "Authorization": `Bearer ${sessionStorage.id_token}`
    }, headers);
}

我的发帖要求是这样的:

   static post (url, params, headers = {}) {
        return request
            .post(Api.prefix(url))
            .set(Api.headers(headers))
            .send(params);
    }

由于application / json无法发送文件数据(据我了解),因此我不得不更改我的上一个表单发送数据的方式。

根据https://visionmedia.github.io/superagent/#multipart-requests,您不能将.send和.attach混合使用,并且无法通过atm进行操作...

因此,我修改了旧的发帖请求,虽然有很多.field()有点烦人,但现在看来别无选择。至少可以正常工作!

static post (url, params, headers = {}) {
    if (url.match(/something/)) {
        return request
            .post(Api.prefix(url))
            .set(Api.headers(headers))
            .send(params);
    } else {
        return request
            .post(Api.prefix(url))
            .set(Api.headers(headers))
            .field('x', params.x)
            .field('x', params.x)
            .field('x', params.x)
            .field('x', params.x)
            .field('x', params.x)
            .field('x', params.x)
            .field('x', params.x)
            .field('x', params.x)
            .field('x', params.x)
            .field('x', params.x)
            .attach('logo', params.logo)
            .attach('flyer', params.flyer);
    }

此外,我只是将File对象发送到我的状态(然后以与以前相同的方式发送到我的商店中):

handleChangeFilePath = prop => (event) => {
    this.setState({
        [prop]: event.target.files[0],
        [prop + 'Preview']: event.target.files[0]
    });
    if ([prop][0] === 'flyer') {
        this.updateNumberOfPages(event.target.files[0]);
    }
};

现在我的数据库已按我的意愿填满,我可以在表格末尾上传文件,也就是在将文件发送到商店后的方式! :)