React redux验证上传的json文件中的道具

时间:2017-08-15 15:51:05

标签: reactjs redux react-redux

我正在尝试创建一个简单的用户界面,可以上传一个json文件,然后检查是否有某些键。那么在我的代码中发生的是,当有人上传json文件时,会调度一个动作。在此操作中,我读取了文件,并检查了某些键,如果上传的文件中没有键,我将其推送到数组。我的问题是,返回状态时会出现问题,因为在状态中没有正确设置missingProps。

    const reader = new FileReader();
    const missingProps = [];
    reader.onload = function(e) {
        const result = JSON.parse(e.target.result);
        // const formatted = JSON.stringify(result, null, 2);

        function checkProperties(property, object) {
            property in object ? console.log('Child detected') : missingProps.push(property);
        }
        checkProperties('keyExists', result);
        checkProperties('keyNotExist', result);
    }
    reader.readAsText(acceptedFiles[0]);

    return {
        type: UploadActionTypes.UPLOAD_JSON,
        json: acceptedFiles[0],
        missingProps: missingProps
    };

我的移民思想是因为它是一个回调函数,所以在评估函数之前返回状态。此外,当我检查控制台时,它说下一个状态中的missingProps是一个数组(0),但如果我打开状态对象,我可以看到它实际上有一个键。

在过去的3个小时里,我一直在玩thunk中间件和承诺,但我似乎无法让它工作。 可以在此处找到代码的链接。 https://codesandbox.io/s/50r2vwmx1n

如果您更喜欢查看原始代码,我会在下面粘贴它。

index.js

import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import { applyMiddleware, createStore } from 'redux';
import UploadReducer from './reducers/upload';
import UploadContainer from './containers/UploadContainer';

import { createLogger } from "redux-logger";
import thunk from "redux-thunk";
import promise from "redux-promise-middleware";

const middleware = applyMiddleware(promise(), thunk, createLogger());

const store = createStore(UploadReducer, middleware);

store.subscribe(() => {
    console.log("Store changed", store.getState());
})

render(
    <Provider store={store}>
        <UploadContainer />
    </Provider>,
    document.getElementById('root')
)

UploadContainer

import React, { Component } from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import * as UploadActionCreators from '../actions/upload';
import Upload from '../components/Upload';

class UploadContainer extends Component {

    render() {
        const { dispatch, json, missingProps } = this.props;
        const uploadJson = bindActionCreators(UploadActionCreators.uploadJson, dispatch);

        return (
            <div className="App">
                <div className="App-header">
                    <h2>Welcome to React</h2>
                </div>
                <Upload onDrop={uploadJson} json={this.props.json}/>
            </div>
        );
    }
}

const mapStateToProps = state => (
    {
        json: state.json,
        missingProps: state.missingProps
    }
);

export default connect(mapStateToProps)(UploadContainer);

UploadComponent

import React, { PropTypes } from 'react';
import Dropzone from 'react-dropzone';

const Upload = props => {
    return (
        <div className="container">
            <h1>Hello React!</h1>
            <Dropzone onDrop={props.onDrop}>
                {props.json ? props.json.name : "Drop some json"}
            </Dropzone>
            <p>Missing properties:</p>
                {props.missingProps ? props.missingProps.map(prop => <li>{prop}</li>) : ''}
            <ul>
            </ul>

        </div>
    )
}

Upload.propTypes = {
    onDrop: PropTypes.func.isRequired
};

export default Upload;

UploadActionType

export const UPLOAD_JSON = 'upload/UPLOAD_JSON';

UploadAction

import * as UploadActionTypes from '../actiontypes/upload';

// export const uploadJson = (acceptedFiles, rejectedFiles) => {
//     return {
//         type: UploadActionTypes.UPLOAD_JSON,
//         acceptedFiles,
//         rejectedFiles
//     };
// };

export const uploadJson = (acceptedFiles, rejectedFiles) => {
    const reader = new FileReader();
    const missingProps = [];
    reader.onload = function(e) {
        const result = JSON.parse(e.target.result);
        // const formatted = JSON.stringify(result, null, 2);

        function checkProperties(property, object) {
            property in object ? console.log('Child detected') : missingProps.push(property);
        }
        checkProperties('keyExists', result);
        checkProperties('keyNotExist', result);
    }
    reader.readAsText(acceptedFiles[0]);

    return {
        type: UploadActionTypes.UPLOAD_JSON,
        json: acceptedFiles[0],
        missingProps: missingProps
    };
};

1 个答案:

答案 0 :(得分:2)

读取文件是异步的。但是你的行动创造者会被执行并立即返回。

{ type: UploadActionTypes.UPLOAD_JSON, json: acceptedFiles[0], missingProps: missingProps };

到商店。但是missProps尚未填补。你需要使用redux-thunk。

export const uploadJson = (acceptedFiles, rejectedFiles) => (dispatch) => {
    const reader = new FileReader();
    const missingProps = [];
    reader.onload = function(e) {
        const result = JSON.parse(e.target.result);
        // const formatted = JSON.stringify(result, null, 2);

        function checkProperties(property, object) {
            property in object ? console.log('Child detected') : missingProps.push(property);
        }
        checkProperties('keyExists', result);
        checkProperties('keyNotExist', result);
        dispatch({
            type: UploadActionTypes.UPLOAD_JSON,
            json: acceptedFiles[0],
            missingProps
        })
    }
    reader.readAsText(acceptedFiles[0]);

};

顺便说一句,reducer中的console.log应该如下console.log("missing properties:", action.missingProps);

应该通过输出undefined代替[]

的事实暗示