我正在尝试创建一个简单的用户界面,可以上传一个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
};
};
答案 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
代替[]