2017-08-15 98 views
0

終極版驗證道具我試圖創建一個簡單的用戶界面,它應該可以上傳一個JSON文件,然後如果某些鍵在它就會得到遏制。因此,在我的代碼中發生的事情是,當有人上傳json文件時,會分派一個操作。在這個動作中,我讀取文件,並檢查某些鍵,如果上傳的文件中沒有鍵,我將其推送到一個數組。我的問題是,當狀態返回時出現錯誤,因爲在狀態中missingProps沒有正確設置。陣營從上傳的JSON文件

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 
    }; 

我immiediate的想法是,因爲它的回調函數,狀態返回之前函數的評估。另外,當我檢查控制檯時,它說在下一個狀態下的missingProps是一個Array(0),但是如果我打開狀態對象,我可以看到它實際上有一個鍵。

我被玩弄的thunk中間件和承諾,在過去的3個小時,但我似乎無法得到它的工作。 可以在這裏找到代碼的鏈接。 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 
    }; 
}; 

回答

2

讀取文件是異步的。但是你的動作創建者被執行並立即返回。

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

商店。但missingProps尚未填充。你需要使用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]); 

};

順便說一句,你在減速的console.log應該是這樣的console.log("missing properties:", action.missingProps);

應該通過這樣的事實暗示,它輸出的undefined代替[]