更新Redux状态后无法重新呈现页面

时间:2019-03-08 05:36:27

标签: node.js reactjs redux

我在这里获取“ / dashboard / gdrive”中的Google驱动器文件列表。还有一个上传新文件的事件。在上传redux状态时,表明新文件已存储在状态中,但是在重新渲染时,我无法访问存储状态。

这是代码块

import React, { Component } from 'react';
import PropTypes from "prop-types";
import {connect} from "react-redux";
import {logoutUser} from "./../../actions/authActions.js";
import {syncCloud} from "./../../actions/cloudActions.js";
import {uploadFile} from "./../../actions/cloudActions.js";

class Gdrive extends Component {
    constructor(){
        super();
        this.state={
            file: null
        }
        this.onChange = this.onChange.bind(this);
        this.onSubmit = this.onSubmit.bind(this);
        this.handleCancelEvent = this.handleCancelEvent.bind(this);
    }
    onChange(e){
        this.setState({
            file: e.target.files[0]
        });
    }
    onSubmit(e){
        e.preventDefault();
        const data = new FormData();
        data.append('filename', this.state.file);
        this.props.uploadFile(data);
    }
    handleCancelEvent(){
        this.setState({
            file: null
        })
    }
    render() {    
    return (
        <div>
            <table>
                <thead>
                    <tr><th>fileid</th><th>filename</th></tr>
                </thead>
                <tbody>
                    {this.props.cloud.files.data.map(file =>(
                        <tr>
                            <td>{file.id}</td>
                            <td>{file.name}</td>
                        </tr>
                    ))}
                </tbody>
            </table>
            <fieldset>
                <form noValidate onSubmit={this.onSubmit}>
                <div>
                    <label>filename</label>
                    <input type="file" onChange={this.onChange} name= "filename"></input>
                </div>
                <div>
                    <button type="submit">Upload</button> 
                    <button onClick={this.handleCancelEvent}>Cancel</button>
                </div>
                </form>
            </fieldset>
        </div>
    )
  }
}
Gdrive.propTypes = {
    logoutUser: PropTypes.func.isRequired,
    auth: PropTypes.object.isRequired
  };
const mapStateToProps = state => ({
    auth: state.auth,
    cloud: state.cloud
});
export default connect(
    mapStateToProps,
    { logoutUser, syncCloud, uploadFile }
  )(Gdrive);

这是uploadFile操作

export const uploadFile = (file) => dispatch => {
axios.post('/gdrive/upload', file)
.then(rslt => {
    dispatch({
        type: UPLOAD_FILE,
        payload: {id: rslt.data.fileid, name: rslt.data.filename}
    })
})
.catch(err => {
    dispatch({
        type: GET_ERRORS,
        payload: err
    })
});

}

这是减速器

import {SYNC_CLOUD, UPLOAD_FILE} from './../actions/types';

const initialState = {
    files: {}
};

export default function(state=initialState, action){
    switch(action.type){
        case SYNC_CLOUD:
            return{
                ...state,
                files: action.payload
            };
        case UPLOAD_FILE: 
            return{
                ...state,
                files: state.files.data.concat(action.payload),
            };
        default: 
            return state;
    }
}

error screenshot

2 个答案:

答案 0 :(得分:0)

mapDispatchToProps

connect参数必须是一个函数。要么做这样的事情

const mapDispatchToProps= dispatch => bindActionCreators(
    { logoutUser, syncCloud, uploadFile },
    dispatch
)

或者,以null作为您的mapDispatchToProps,并在您的组件中使用类似this.props.dispatch(uploadFile(data))这样的动作创建者

答案 1 :(得分:0)

我认为您的化简器映射错误,这里的关键是将初始状态声明为空文件而不是空对象。并使用api(payload)的响应来隐藏现有数组。

将您的减速器更改为以下内容:

 import {SYNC_CLOUD, UPLOAD_FILE} from './../actions/types';

const initialState = {
    files: []
};

export default function(state=initialState, action){
    switch(action.type){
        case SYNC_CLOUD:
            return{
                ...state,
                files: action.payload
            };
        case UPLOAD_FILE: 
            return{
                [...state, action.payload],
            };
        default: 
            return state;
    }
}

并将渲染功能更改为

<tbody>
       {this.props.cloud.files.map(file =>(
            <tr>
                 <td>{file.id}</td>
                  <td>{file.name}</td>
              </tr>
                ))}
 </tbody>