【问题标题】:How to access a HTML element inside a control from the store?如何从商店访问控件内的 HTML 元素?
【发布时间】:2016-02-07 10:30:58
【问题描述】:

我正在使用 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 -> Dispatcher -> Store。

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;

因此,由于我只能从定义组件的 jsx 文件中直接访问错误 div(或任何其他 react-components HTML 元素)这一事实(如果我错了,请纠正我) ,我创建了handleError 函数,它与有效负载一起传输到存储本身,如果从服务器发回错误,可以调用它。

此实现有效,但我正在寻找一种更优雅的方式来执行此操作(如果有的话)。

非常感谢您的任何建议。

【问题讨论】:

    标签: javascript html ajax reactjs-flux


    【解决方案1】:

    react 的主要思想是您直接操作 DOM。 (有一些例外,例如添加/删除侦听器)。

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

    并且不要让 store 直接调用元素内部的函数:组件应该真正是自包含的,响应 props 和用户输入。相反,在您的组件中放置一个侦听器,如果您的商店发生变化,它会获取新数据。

    类似这样的:

    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);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-14
      • 1970-01-01
      • 1970-01-01
      • 2020-08-31
      • 2021-06-03
      • 2016-02-06
      • 1970-01-01
      相关资源
      最近更新 更多