加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

reactjs – “Uncaught TypeError:无法读取未定义的属性’类型

发布时间:2020-12-15 09:32:54 所属栏目:百科 来源:网络整理
导读:我原本以为这是react-redux,axios,lodash和/或react-dropzone的问题;但是,文件上传正常,但仍会触发此错误. (即使在控制台中显示“失败”,文件也会被发布到服务器). 我开始认为这个问题可能与react-router-redux有关,基于我在这里读到的内容: https://github
我原本以为这是react-redux,axios,lodash和/或react-dropzone的问题;但是,文件上传正常,但仍会触发此错误. (即使在控制台中显示“失败”,文件也会被发布到服务器).

我开始认为这个问题可能与react-router-redux有关,基于我在这里读到的内容:

https://github.com/reactjs/react-router-redux/issues/182

但是,这些建议对我不起作用.

无论如何,我得到一个未捕获的TypeError:无法读取未定义的属性’type’我无法确定是什么原因导致它或如何解决它.以下是错误的一些屏幕截图:

所以这里应该是react-router的相关内容.只是不确定发生了什么.

切入点:

// ./react/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore,applyMiddleware,compose } from 'redux';
import thunk from 'redux-thunk';
import { BrowserRouter,Switch,Route } from 'react-router-dom';
import { routerMiddleware,ConnectedRouter } from 'react-router-redux';

import createHistory from 'history/createBrowserHistory';

// Render on every route
import App from './components/app';
import Navbar from './containers/global/navbar';
import Footer from './containers/global/footer';

// Reducers 
import rootReducer from './reducers';

// SCSS for the project
import styles from '../assets/scss/main.scss';

// IE polyfill error fix
require('es6-promise').polyfill();
var axios = require('axios');

const history = createHistory();

const initialState = {};
const enhancers = [];
const middleware = [thunk,routerMiddleware(history)];

if (process.env.NODE_ENV === 'development') {
    const devToolsExtension = window.devToolsExtension

    if (typeof devToolsExtension === 'function') {
        enhancers.push(devToolsExtension())
    }
}

const composedEnhancers = compose(applyMiddleware(...middleware),...enhancers);
const protectedRoute = compose(Timers,RequireAuth);

const store = createStore(rootReducer,initialState,composedEnhancers);

ReactDOM.render(
    <Provider store={store}>
        <ConnectedRouter history={history}>
            <div>
                <Navbar />
                <App />
                <Switch>
                      // various routes go here...
                </Switch>
                {/*<Footer />*/}
            </div>
        </ConnectedRouter>
    </Provider>,document.querySelector('.container'));

全局缩减器以及与触发错误的操作有关的缩减器.

// ./react/reducers/index.js
import { combineReducers } from 'redux';
import { reducer as form } from 'redux-form';
import { routerReducer } from 'react-router-redux';
import documentReducer from './documents';

const rootReducer = combineReducers({
    form,router: routerReducer,documents: documentReducer,});

export default rootReducer;
// ./react/reducers/documents.js
import {
    DOCUMENTS
} from '../actions/documents';

export default function(state = {},action) {
    switch(action.type) {
        case DOCUMENTS:
            return { 
                ...state,survey_id: action.payload.survey_id,};
        default:
            return state;
    }

    return state;
}

最后,引发错误时调用的操作.需要指出的一件重要事情是:当axios.post不在_.map中时(实际上是任何类型的数组迭代),都不会发生错误.但是,这只发送一个不是我追求的行为的文件.

// ./react/actions/documents.js
import _ from 'lodash';
import axios from 'axios';
import { push } from 'react-router-redux';
import { ROOT_URL } from '../../config/config.json';

// Establish the different types
export const DOCUMENTS = 'documents';

export function submitDocument(files) {
    const uploaders = _.map(files,f => {
        const formData = new FormData();

        formData.append('file',f);

        return axios.post(
            `${ROOT_URL}/api/documents/fileupload`,formData,{ headers: 
                { 
                    'content-type': 'multipart/form-data','Authorization': 'JWT ' +  sessionStorage.getItem('token')
                }
            }            
        )

    });

    axios.
        all(uploaders)
        .then(response => {
            console.log('Success');
        })
        .catch(error => {
            console.log('Failed');
        })
}

调用该操作的容器也可能有用:

// ./react/containers/documents/submit_documents.js
import _ from 'lodash';
import React,{ Component } from 'react';
import { connect } from 'react-redux';
import { submitDocument } from '../../actions/documents';
import Dropzone from 'react-dropzone';

class SubmitDocuments extends Component {

    constructor() {
        super();
        this.state = {
            filesToBeSent: [],filesPreview: [],}

        this.handleClick = this.handleClick.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
        this.onDrop = this.onDrop.bind(this);
    }

    handleSubmit(event) {
        event.preventDefault();
        this.props.submitDocument(this.state.filesToBeSent);
    }

    onDrop(acceptedFiles) {
        var filesToBeSent = this.state.filesToBeSent;       
        _.map(acceptedFiles,f => {
            filesToBeSent.unshift(f);
        });

        filesToBeSent = _.uniqBy(filesToBeSent,'name');

        var filesPreview = [];

        _.map(filesToBeSent,i => {
            filesPreview.unshift(
                <div key={i.name}>
                    <h5>{i.name} - {i.size} bytes</h5>
                </div>
            )            
        });

        this.setState({
            filesToBeSent,filesPreview
        });
    }

    render() {
        return (
            <form onSubmit={this.handleSubmit}>
                <div className='panel panel-default'>
                    <div className='panel-heading'>
                        <h4><strong>Submit Documents</strong></h4>
                    </div>

                    <div className='panel-body'>
                        <Dropzone className='dropzone' onDrop={this.onDrop}> 
                            <h3>Click to add files or drag files here to upload</h3>
                        </Dropzone>
                        {this.state.filesPreview}
                        <button type='submit' disabled={this.state.filesPreview.length < 1} className='btn btn-primary'>Submit</button>
                        <button type='button' className='btn btn-danger' onClick={this.handleClick}>Cancel</button>
                    </div>
                </div>
            </form>
        ); 
    }
}

function mapStateToProps(state) {
    return {
        survey_id: state.documents.survey_id
    }
}

export default connect(mapStateToProps,{ submitDocument })(SubmitDocuments);

另外,因为错误中提到了webpack,所以这里是它的配??置:

var path = require('path')
var webpack = require('webpack')
var BundleTracker = require('webpack-bundle-tracker')
var ExtractTextPlugin = require('extract-text-webpack-plugin')

module.exports = {
  context: __dirname,entry: [
    '../react/index'  
  ],output: {
      path: path.resolve('./src/assets/bundles/'),filename: './js/[name]-[hash].js'
  },plugins: [
    new BundleTracker({filename: './src/config/webpack-stats.json'}),new ExtractTextPlugin({filename: './css/[name].[hash].css',allChunks: true})
  ],module: {
    loaders: [
      // {test: /.(jpe?g|png|gif|svg)$/i,loader: "url-loader?name=img/[name].[ext]"},{ 
        test: /.jsx?$/,exclude: /node_modules/,loader: 'babel-loader',query: {
          presets: ["react","es2015","stage-1"]
        }
      },{
        test: /.json$/,loader: ['json-loader'] 
      },{
        test: /.scss$/,loader: ['style-loader','css-loader','sass-loader'] 
      },use: ExtractTextPlugin.extract({
          fallback: 'style-loader',use: 'css-loader'
        })      
      },],},resolve: {
    extensions: ['*','.js','.jsx','.gif']
  }
}

无论如何,不??知道是什么导致它,并且已经尝试解决它几天了.一切都运行正常,否则,它看起来不专业.

解决方法

Redux thunk个动作创建者返回带有参数(dispatch,getState)的函数,并且在该函数内部,当您的数据可用时,您可以调度()动作.

您的代码可能会出错,因为您根本没有从动作创建者那里返回任何内容.由于它是异步的,返回内部函数:

export function submitDocument(files) {
    return function (dispatch,getState) {
        const uploaders = _.map(files,f => {
            const formData = new FormData();

            formData.append('file',f);

            return axios.post(
                `${ROOT_URL}/api/documents/fileupload`,{ headers:
                    {
                        'content-type': 'multipart/form-data','Authorization': 'JWT ' +  sessionStorage.getItem('token')
                    }
                }
            )

        });

        axios.
            all(uploaders)
            .then(response => {
                console.log('Success');
                dispatch({ type: DOCUMENTS,payload: ... });
            })
            .catch(error => {
                console.log('Failed');
                dispatch({ type: 'YOUR_ERROR_TYPE',payload: ... });
            })
        };
    }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读