Programing

"Uncaught TypeError: 정의되지 않은 속성 '유형'을 읽을 수 없으며, 관련 내용이 명확하지 않음

c10106 2022. 4. 2. 09:35
반응형

"Uncaught TypeError: 정의되지 않은 속성 '유형'을 읽을 수 없으며, 관련 내용이 명확하지 않음

난 원래 이 문제가react-redux,axios,lodash, 및/또는react-dropzone; 그러나, 파일은 잘 업로드되고 있지만, 이 오류는 여전히 트리거된다. (콘솔에 "실패"라고 되어 있음에도 불구하고, 파일은 서버에 게시되고 있다.)

나는 그 문제가 관련이 있다고 생각하기 시작했다.react-router-redux여기서 읽은 내용에 따르면:

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

하지만, 그 제안들은 나에게 효과가 없다.

어쨋든, 난 지금..Uncaught TypeError: Cannot read property 'type' of undefined어떤 원인이 있는지, 어떻게 해결해야 하는지 잘 모르겠다.오류에 대한 몇 가지 스크린샷:

정의되지 않은 선을 긋다

그래서 여기에 관련되어야 할 것이 있다.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;
}

마지막으로 오류가 발생할 때 호출되는 동작.한 가지 중요한 점은 에러가 없을 때(사실상 어떤 종류의 어레이 반복도) 오류가 발생하지 않는다는 것이다. 그러나, 그것은 단지 내가 쫓는 행동이 아닌 하나의 파일만 보낸다.

// ./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'] 
      },
      {
        test: /\.scss$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: 'css-loader'
        })      
      },   
    ],
  },

  resolve: {
    extensions: ['*', '.js', '.jsx', '.gif']
  }
}

아무튼 무엇이 원인인지 잘 모르고 며칠째 해결하려고 애쓰고 있다.그렇지 않으면 모든 게 잘 돼, 프로답지 않게 보일 뿐이야.

내 경우, LastPass 확장이 내 코드가 아닌 이 오류를 발생시키고 있었다.onloadwff.js).
확장을 제거하여 수정하십시오.


Lastpass-cli/issions/428#comment에 따라 LastPass 확장 설정을 클릭했을 때만 실행되도록 업데이트하면 이 문제를 방지할 수 있다.

Reducx Thunk 작업 작성자는 인수를 사용하여 함수를 반환함(dispatch, getState)그리고 그 기능 안에선dispatch()데이터를 사용할 수 있는 경우 작업.

작업 작성자로부터 어떤 것도 반환하지 않았기 때문에 코드가 잘못되었을 수 있다.비동기식이므로 내부 기능을 반환하십시오.

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`,
                formData,
                { 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: ... });
            })
        };
    }

나는 Redex-toolkit과 비슷한 문제에 직면하고 있었다.잘못된 Reducer-Action 수입으로 인해 발생한다는 것을 알게 되었다.NAMED 가져오기여야 하는 곳에 DEFAULT 가져오기를 사용했기 때문에 발생한 것이다.

예를 들면

//Reducer Action export from userSlice
export const { addUser } = userSlice.actions

//Wrong Reducer Action Import
import addUser from '../reducers/userSlice'

//Correct Reducer Action Import
import {addUser} from '../reducers/userSlice'

참조URL: https://stackoverflow.com/questions/48099807/uncaught-typeerror-cannot-read-property-type-of-undefined-and-unclear-what

반응형