【问题标题】:Intermittent React Uncaught Error: Objects are not valid as a React child间歇性 React 未捕获错误:对象作为 React 子项无效
【发布时间】:2018-04-06 05:04:02
【问题描述】:

我有一个 Header 组件,它根据用户是否登录来呈现一些链接。

此组件加载正常,显示登录和注册链接正常。单击这些链接会将我带到那些功能正常的组件。登录后,标题会更改以显示注销链接。

但是,当我退出时,出现问题。登录和注册链接显示正常,但它们不再起作用。单击注册链接会出现以下错误:

未捕获的错误:对象作为 React 子对象无效(找到:对象 带键 {})。如果您打算渲染一组孩子,请使用 数组代替或使用 createFragment(object) 从 反应附加组件。检查Signin的渲染方法。

再次点击链接会产生这样的结果:

bundle.js:4297 未捕获类型错误:无法读取属性“getHostNode” 为空

我在这里读过类似的问题,通常它们涉及尝试渲染对象而不是其属性之一的人。但是,这里不是这种情况——或者我错过了什么?

我的代码:

标题:

import React, {Component} from 'react';
import {connect} from 'react-redux';
import {Link} from 'react-router';

class Header extends Component{
    renderLinks(){
        if(this.props.authenticated){
            return <li className="nav-item ">
                <Link className="nav-link" to="/signout">Sign Out</Link>
            </li>
        }else{
            return [<li className="nav-item page-scroll" key={1}>
                        <Link className="nav-link page-scroll" to="/signin">Sign In</Link>
                    </li>,
                    <li className="nav-item" key={2}>
                        <Link className="nav-link page-scroll" to="/signup">Sign Up</Link>
                    </li>
           ]
        }
    }

    render() {
        return (
            <div className="container-fluid header">
                <nav className="navbar navbar-toggleable-md navbar-inverse bg-inverse">
                    <div className="navbar-nav">
                            <Link to="/" className="navbar-brand">
                                    <img alt="Trellis" src="../../images/trellis.png" />
                            </Link>
                            <ul className="nav navbar-nav">
                                {this.renderLinks()}
                            </ul>
                        </div>

                </nav>
            </div>
        );
    }
}

function mapStateToProps(state){
    return{
        authenticated: state.auth.authenticated
    };
}
export default connect(mapStateToProps)(Header);

登录组件:

import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';
import * as actions from '../../actions';
import { connect } from 'react-redux'; 
import { Link } from 'react-router';

class Signin extends Component {

    handleFormSubmit({ email, password }) {
        this.props.signInUser({email, password});
    }

    renderInput(field) {
        if(!field.className) { field.className = "form-control" }
        if(!field.type) { field.type = "text" }

        return (
            <div>
                <Field name={field.name} id={field.name} type={field.type} className={field.className} component="input" />
            </div>
        )
    }
    renderAlert(){
        if(this.props.errorMessage){
            return(
                    <div className="alert alert-danger">
                        <strong>Oops!</strong> {this.props.errorMessage}
                    </div>
                );
    }
}

    render() {
        const { handleSubmit } = this.props

        return (
            <form className="sign-in" onSubmit={handleSubmit(this.handleFormSubmit.bind(this))}>
                <fieldset className="form-group">
                    <label>Email:</label>
                    {this.renderInput({ name: "email", type: "email" })}
                </fieldset>
                <fieldset className="form-group">
                    <label>Password:</label>
                    {this.renderInput({ name: "password", type: "password" })}
                </fieldset>
                <div className="password-forgot">
                    <Link to="/reset-password">I forgot my password</Link>
                </div>
                {this.renderAlert()}
                <button action="submit" className="btn btn-primary">Sign in</button>
            </form>
        )
    }
}

function mapStateToProps(state){
    return{errorMessage: state.auth.error};
 }

Signin = connect(mapStateToProps, actions)(Signin)

export default reduxForm({
  form: 'signin'
})(Signin)

退出组件:

import React, {Component} from 'react';
import {connect} from 'react-redux';
import * as actions from '../../actions';

class Signout extends Component {
    componentWillMount() {
        this.props.signOutUser();
    }
    render() {
        return <div>Sorry to see you go!</div>;
    }
}

export default connect(null, actions)(Signout);

登录操作:

export function signInUser(props) {
    const { email, password } = props;
    return function(dispatch){
        axios.post(`${ROOT_URL}/signin`, {email, password})
            .then(response => {
                localStorage.setItem('user', JSON.stringify(response.data));
                dispatch({ type: AUTH_USER });
                browserHistory.push('/dashboard');
        })
            .catch((err) => {
                console.log(JSON.stringify('login error:', err));
                dispatch(authError(SIGNIN_FAILURE, 'Bad login credentials'));
        });
    };
}

退出操作:

export function signOutUser() {
    localStorage.clear();
    return { type: UNAUTH_USER };
}

【问题讨论】:

  • errorMessage 是什么?只是一个字符串?你能补充一下吗
  • 登录组件的errorMessage?是的,它是一个字符串,当有一个测试时它呈现良好。
  • 嘿,等一下,就是这样。那是一个物体。现在可以使用了。
  • 哈哈,我也这么想。这是 SignIn 渲染中唯一可以做到的:P
  • 完美。你能发布一个答案,我会接受吗?

标签: javascript reactjs react-router react-redux


【解决方案1】:

(根据原帖中的cmets)

问题出在您调用 renderAlert() 函数的 SignIn 渲染组件中,该函数将 this.props.errorMessage 作为 JSX 元素的一部分返回。这是 SignIn 呈现的 JSX 中唯一可能存在问题的部分(根据您的代码)。

原来this.props.errorMessage 实际上是一个对象,而不是你想象的字符串,因此将对象视为 React 子级的错误。

【讨论】:

    猜你喜欢
    • 2017-08-04
    • 2017-04-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-27
    • 2018-11-12
    • 1970-01-01
    • 2021-04-04
    相关资源
    最近更新 更多