React无法找到事件

4

我正在实现一个非常简单的React登录页面。我从以下组件Account开始。

var Account = React.createClass({

getInitialState: function() {
    return {
        showSignUp: false,
        showLogin: true
    }
},

update: function(data) {
    this.setState(data);
},

render: function() {
    if(this.state.showSignUp) {
        return <SignUp/>
    }
    else {
        return <Login update={this.update}/>
    }
}

});

正如预期的那样,登录组件被显示并呈现如下内容:
return (
        <div>
            <p><input type="text" placeholder={Language.languagePack.account.username} onChange={this.usernameChange}/></p>
            <p><input type="password" placeholder={Language.languagePack.account.password} onChange={this.passwordChange}/></p>
            <p><a onClick={this.performLogin}>{Language.languagePack.account.login}</a></p>
            <p><a onClick={this.handleSignUp}>{Language.languagePack.account.signUp}</a></p>
            <p>{failedMessage}</p>
        </div>
    )

这一切都很正常。应用程序通过onChange钩子接收到更改。如果用户点击“注册”,则会调用以下代码:
handleSignUp: function() {
    this.props.update({showSignUp: true, showLogin: false})
},

这会调用Account类中的update方法,该方法会更新状态并导致重新渲染。这就是使其切换到SignUp组件的原因。

return (
        <div id="signUp">
            <p><input type="text" placeholder={Language.languagePack.account.username} onChange={this.usernameChange} /></p>
            <p><input type="password" placeholder={Language.languagePack.account.password} onChange={this.passwordChange} /></p>
            <p><input type="email" placeholder={Language.languagePack.account.email} onChange={this.emailChange} /></p>
            <p><a onClick={this.handleSignUp}>{Language.languagePack.account.signUp}</a></p>
        </div>
    )

由于某种原因,这里没有触发任何事件。onChange或onClick似乎未被注册。我认为这与我的实现有关,根据状态更改切换组件来呈现不同的组件。我的问题是,为什么会发生这种情况,我在React中哪个部分存在误解导致了这种情况?

完整的类

登录组件

var Login = React.createClass({

getInitialState: function() {
    return {
        username: '',
        password: '',
        failed: false
    }
},

usernameChange: function(event) {
    this.setState({
        username: event.target.value,
        failed: false
    });
},

passwordChange: function(event) {
    this.setState({
        password: event.target.value,
        failed: false
    });
},

performLogin: function() {
    var username = this.state.username;
    var password = this.state.password;

    console.log("Attempting login with username " + username + " and password " + password);

    var _this = this;

    Api.login(username, password, function(response) {
        _this.props.update({user: response, loggedIn: true});
    },
    function(response) {
        _this.setState({failed: true});
    })
},

handleSignUp: function() {
    this.props.update({showSignUp: true, showLogin: false})
},

render: function() {
    var failedMessage = null;

    if(this.state.failed) {
        failedMessage = <div className="failed-auth">{Language.languagePack.account.invalidCredentials}</div>;
    }

    return (
        <div>
            <p><input type="text" placeholder={Language.languagePack.account.username} onChange={this.usernameChange}/></p>
            <p><input type="password" placeholder={Language.languagePack.account.password} onChange={this.passwordChange}/></p>
            <p><a onClick={this.performLogin}>{Language.languagePack.account.login}</a></p>
            <p><a onClick={this.handleSignUp}>{Language.languagePack.account.signUp}</a></p>
            <p>{failedMessage}</p>
        </div>
    )
}
});

注册组件

var SignUp = React.createClass({

getInitialState : function() {
    return {
        username: '',
        password: '',
        email: ''
    }
},

usernameChange: function(event) {
    this.setState({
        username: event.target.value
    });
},

passwordChange: function(event) {
    this.setState({
        password: event.target.value
    });
},

emailChange: function(event) {
    this.setState({
        email: event.target.value
    });
},

handleSignUp : function() {
    var username = this.state.username;
    var password = this.state.password;
    var email = this.state.email;

    console.log("Signing up with username=" + username + " and password=" + password + "and email=" + email);
},

handleLogin : function() {
    console.log("Fired!");
},

render: function () {
    return (
        <div id="signUp">
            <p><input type="text" placeholder={Language.languagePack.account.username} onChange={this.usernameChange} /></p>
            <p><input type="password" placeholder={Language.languagePack.account.password} onChange={this.passwordChange} /></p>
            <p><input type="email" placeholder={Language.languagePack.account.email} onChange={this.emailChange} /></p>
            <p><a onClick={this.handleSignUp}>{Language.languagePack.account.signUp}</a></p>
        </div>
    )
}
});

你在切换到注册页面后能切换回登录页面吗? 如果你在注册页面更改了用户名,当你再次切换回登录页面时,它会改变吗? - Victor - Reinstate Monica
不,没有任何事件被触发,也没有任何地方发生变化。我无法切换回去,因为我无法将事件附加到注册视图中的任何内容。 - christopher
如果您更改Account的初始状态,首先显示注册表单呢?仍然没有事件吗? - Victor - Reinstate Monica
你能否创建一个 http://jsfiddle.net/ 来重现这个问题?我没有看到任何明显的错误,而且你也没有发布实际呈现组件的代码。 - Felix Kling
哦,在顶部靠右边。那么,您无法复现的事实可能意味着问题出在其他地方。 - Felix Kling
显示剩余3条评论
3个回答

1
您的代码确实可以工作;但是,我已经删除了对 language.LanguagePack 的引用,因为在您提供的代码中没有定义它。如果出现JavaScript错误,它将阻止代码运行。

https://jsfiddle.net/tqz3skcr/2/

var SignUp = React.createClass({

getInitialState : function() {
    return {
        username: '',
        password: '',
        email: ''
    }
},

usernameChange: function(event) {
    console.log('username Changed');
    this.setState({
        username: event.target.value
    });
},

passwordChange: function(event) {
    console.log('password Changed');
    this.setState({
        password: event.target.value
    });
},

emailChange: function(event) {
    console.log('email changed');
    this.setState({
        email: event.target.value
    });
},

handleSignUp : function() {
    var username = this.state.username;
    var password = this.state.password;
    var email = this.state.email;

    console.log("Signing up with username=" + username + " and password=" + password + "and email=" + email);
},

handleLogin : function() {
    console.log("Fired!");
},

render: function () {
    return (
        <div id="signUp">
            <p><input type="text" onChange={this.usernameChange} /></p>
            <p><input type="password" onChange={this.passwordChange} /></p>
            <p><input type="email" onChange={this.emailChange} /></p>
            <p><a onClick={this.handleSignUp}></a></p>
        </div>
    )
}
});

ReactDOM.render(
    <SignUp />,
    document.getElementById('container')
);

我以非常相似的方式解决了这个问题。剥离了所有无用的东西,回到了最基本的原则。干得好!加150分! - christopher

-1

尝试过了,观察到了相同的行为。第一个组件有事件;第二个没有。 - christopher
虽然这可能在理论上回答了问题,但最好包括回答的关键部分,并提供参考链接。 - Evan Davis

-1

首先,让你的生活更轻松,不要使用像这样的指示器:

{
    showSignUp: true,
    showLogin: false
}

像这样做会更简单,产生的错误会更少:

{
    formToShow: "signUpForm" // or "loginForm" 
}

我会说,如果你开始以这种方式编码,问题将通过“清洁代码魔法”解决))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接