如何从商店访问控件内的HTML元素?

时间:2015-11-06 09:58:55

标签: javascript html ajax reactjs-flux

我正在使用ReactJS + Flux模式创建一个登录页面,我已经做到了,但是如果有更好的方法,我很感兴趣。

我的实现看起来像这样:

LoginForm.jsx

//imports.....
var LoginForm = React.createClass({
    handleSubmit : function(e){
        //take username, password and rememberMe values from the form....
        var error = this.refs.ErrorMsg.getDOMNode();

        error.innerHTML = ""; //reset the error output for every submit

        //if any field is left empty...
        else{ //make an object and forward it to actions....
            LoginActions.login({
                //set username, password and rememberMe fields...
                ErrorCallback : this.handleError
            }); 
        }
    },

    handleError : function(errorMsg){ 
        //function that displays the error msg inside the error div
        this.refs.ErrorMsg.getDOMNode().innerHTML = errorMsg;
    },

    render : function() {
        return(
            //HTML for the form, and:
            <div ref="ErrorMsg"></div>
        )
    }
});
module.exports = LoginForm;

之后,我刚刚创建的对象(不变)像有效负载一样进入Actions - &gt;调度员 - &gt;存储。

LoginStore.js

//imports....
var LoginStore = assign({}, ApplicationStore, {
    login : function(payload){
        //this is the method which is called by the Dispatcher

        /*
            take username, password and rememberMe from payload and create a
            new object for AJAX call....
        */

        var successCallback = function(data, statusText, xhr){
            LoginStore.emit(AppConstants.LOGIN); //there is a LOGIN constant...
            /*
                inside data that I get back from ajax call, 
                there is a Error field which contains the 
                "Wrong username or password" message coming from the server 
                after validation if it failed, or if the credentials are
                fine, it contains an empty string....
            */
            payload.errorCallback(null, data.Error);
        }

        AJAXCall(url, loginInfo, successCallback, payload.errorCallback);
    },

    //dispacher registering....
});
module.exports = LoginStore;

所以,由于事实(纠正我,如果我错了),我可以直接访问错误div(或任何其他react-components HTML元素)仅从定义组件的jsx文件内部,我创建了handleError函数,该函数随有效负载一起传输到商店本身,如果从服务器发回错误,可以调用它。

此实现有效,但我正在寻找一种更优雅的方法(如果有的话)。

非常感谢任何建议。

1 个答案:

答案 0 :(得分:0)

反应的主要思想是你直接操纵DOM。 (有一些例外,例如添加/删除监听器)。

您的反应方式是将错误消息置于状态,如果收到错误消息则更新状态。

并没有让商店直接调用元素内部的一个函数:组件应该是自包含的,响应道具和用户输入。相反,在您的组件中放置一个侦听器,如果您的商店已更改,则会获取新数据。

这样的事情:

var LoginForm = React.createClass({
  getInitialState() {
    return { errorMsg : "" };                // start with empty error message
  },

  componentDidMount() {
    // add listener to store here
    LoginStore.addChangeListener(this._onChangeStore);
  }

  handleSubmit : function(e){
    //take username, password and rememberMe values from the form....
    // No need to empty errorMsg here, we do that when we re-render the form

    //if any field is left empty...
    else{ //make an object and forward it to actions....
      LoginActions.login({
        //set username, password and rememberMe fields...
        //no callback here
      }); 
    }
  },

  _onChangeStore : function(){ 
    // ... go get the error message (if any) from your store
    this.setState({ errorMsg : errorMsgFromStore });
  },

  render : function() {
    return(
      //HTML for the form, and:
        <div ref="ErrorMsg">{this.state.errorMsg}</div>
      )
  }
});

将回调处理程序放在商店内的ajax上。将错误消息保存在那里并发出更改。类似的东西:

var errorCallback = function(data, statusText, xhr){
  this.errorMsg = data.error;  // save the errorMsg in your store
  LoginStore.emit(AppConstants.ERROR); 
}

AJAXCall(url, loginInfo, successCallback, errorCallBack);