【问题标题】:TypeError: Cannot read property 'loading' of undefinedTypeError:无法读取未定义的属性“加载”
【发布时间】:2021-02-17 18:49:16
【问题描述】:

我收到了这个错误。 老实说,我不知道为什么。

我将加载作为道具传递。它在我的 Redux 商店中。

加载的初始状态为假

当我提交时,加载应该更改为 true,您应该会看到错误(例如,如果电子邮件不合法)

signup.js

class signup extends Component {

    constructor() {
        super();
        this.state = {
            email: '',
            password: '',
            confirmPassword: '',
            handle: '',
            errors: {}
        };
    }

    componentWillReceiveProps(nextProps) {
        if (nextProps.UI.errors) {
            this.setState({ errors: nextProps.UI.errors });
        }
    }

    handleSubmit = (event) => {
        event.preventDefault();
        this.setState({
            loading: true
        })
        const newUserData = {
            email: this.state.email,
            password: this.state.password,
            confirmPassword: this.state.confirmPassword,
            handle: this.state.handle
        };

        this.props.signupUser(newUserData, this.props.history);
    }


    handleChange = (event) => {
        this.setState({
            [event.target.name]: event.target.value
        });
    }


    render() {


        const {
            classes,
            UI: { loading } // Thats my ERROR
        } = this.props;
        const { errors } = this.state;


        return (
            <Grid container className={classes.form}>
                <Grid item sm />
                <Grid item sm>
                    <Typography variant="h2" className={classes.pageTitle}>
                        Signup
          </Typography>
                    <form noValidate onSubmit={this.handleSubmit}>
                        <TextField
                            id="email"
                            name="email"
                            type="email"
                            label="Email"
                            className={classes.textField}
                            helperText={errors.email}
                            error={errors.email ? true : false}
                            value={this.state.email}
                            onChange={this.handleChange}
                            fullWidth
                        />
                      ....... // Not important
                     
                        {errors.general && (
                            <Typography variant="body2" className={classes.customError}>
                                {errors.general}
                            </Typography>
                        )}
                        <Button
                            type="submit"
                            variant="contained"
                            color="primary"
                            className={classes.button}
                            disabled={loading}

                        >
                            Sgnup
                            {loading && (
                                <CircularProgress size={30} className={classes.progress} />
                            )}
                        </Button>
                        <br />
                        <small>All ready have  an account ? login in <Link to="/login">here</Link></small>
                    </form>
                </Grid>
                <Grid item sm />
            </Grid>
        )
    }
}

signup.propTypes = {
    classes: PropTypes.object.isRequired,
    user: PropTypes.object.isRequired,
    UI: PropTypes.object.isRequired,
    signupUser: PropTypes.func.isRequired
}

const mapStateToProps = (state) => ({
    user: state.user,
    UI: state.UI
})


export default connect(mapStateToProps, { signupUser })(withStyles(styles)(signup));

UI 减速器.js 加载初始状态为假 我将它作为道具传递给 signup.js(和 login.js)

import {
    SET_ERRORS,
    CLEAR_ERRORS,
    LOADING_UI,
    STOP_LOADING_UI
} from '../types';

const initialState = {
    loading: false,
    errors: null
};

export default function (state = initialState, action) {
    switch (action.type) {
        case SET_ERRORS:
            return {
                ...state,
                loading: false,
                errors: action.payload
            };
        case CLEAR_ERRORS:
            return {
                ...state,
                loading: false,
                errors: null
            };
        case LOADING_UI:
            return {
                ...state,
                loading: true
            };

        default:
            return state;
    }
}

那是我的 store.js

import { createStore, combineReducers, applyMiddleware, compose } from 'redux'
import thunk from 'redux-thunk'


import userReducer from './reducers/userReducer'

import uiReducer from './reducers/uiReducer'

const initialState = {};

const middleware = [thunk]

const reducers = combineReducers({
    user: userReducer,

    ui: uiReducer
})



const composeEnhancers =
    typeof window === 'object' && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
        ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({})
        : compose;

const enhancer = composeEnhancers(applyMiddleware(...middleware));
const store = createStore(reducers, initialState, enhancer);

export default store

如果有任何帮助,我将不胜感激

【问题讨论】:

  • 你的 reducer 中的 UI 状态在哪里?
  • 你能分享你的 combineReducers 吗?
  • 确定我能做到(请一分钟)/这是我第一次使用 react redux :D
  • @DenisSicun 指出了这个问题。你在 combineReducers 的部分状态是 ui 而不是 UI

标签: javascript reactjs react-redux react-props


【解决方案1】:

您在 combineReducers 或 mapStateToProps 中遇到问题。 在 reducer 中它是带有小写字母的 ui,而在 mapStateToProps 中它是大写字母。 更改为这个,它应该可以工作

const mapStateToProps = (state) => ({
    user: state.user,
    UI: state.ui
})

【讨论】:

    【解决方案2】:

    首先,我看到两个错误。一,我认为您正在尝试通过使用 React 状态函数来更新 Redux 状态,但这不是它的工作方式。如果它是一个存在于 React 组件中的状态,那么 React.setState 应该是要走的路。如果您使用的是 Redux,那么我假设通过 Redux 操作/从组件本身调度来更新它的正确方法。我希望这能让你开始调试它。第二,Redux 存储设置不正确,或者对象解构没有按预期工作。

    【讨论】:

    • 您能否展示一下,我在哪一行使用反应状态更新了 redux 状态? (handleSubmit)
    【解决方案3】:

    好吧,您目前的问题在于store.js。您定义initialState = {} 并将其作为参数传递给createStore。然后实际使用这个空对象而不是Reducer.js 中定义的initialState。该对象作为道具传递给signup 类。因此,您无法提取 UI.loading 值,因为没有。

    Reducer.js 导入初始状态,并在调用createStore 时使用它而不是空的initialState

    【讨论】:

      猜你喜欢
      • 2020-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-29
      相关资源
      最近更新 更多