获取URL的时机正确

时间:2016-03-23 02:52:54

标签: reactjs

我希望在初始页面从服务器获取密钥,并使用此密钥在其他组件中获取数据。

var Page = React.createClass({
    getInitialState: function () {
        var key = this.getKey();
        return { key: key };
    },   
    getKey: function () {
        var key;
        $.ajax({
            url: Api.GetMasterkey,
            dataType: 'json',
            data: {
                urlParamter:''
            },
            async: false,
            success: function (data) {
                key = data;
            }.bind(this),
        });

        return key;
    },
    render: function () {
        return (
             <div>
                <ContentA key={this.key} />
                <ContentB key={this.key} />                
             </div>
        );
    }
});

module.exports = Page;

键的值取决于urlPagramter。我尝试在getKey函数中解析url,但我发现url显示的时间是在getInitialState之后。

那么,获取url pagramter的时机是正确的?如果我的设计有误,请随时纠正。

2 个答案:

答案 0 :(得分:2)

首先,这是稍微偏离主题,但请耐心等待:不要在ContentA和ContentB中调用您的道具key。它是React的内部机制的保留prop名称,用于生成react-id,除非是这个目的,否则称之为其他内容。此外,提及this.key毫无意义。它将是this.state.key

根据定义,Ajax操作是异步的,因此keygetKey返回时始终未定义key。如果您在第一次呈现页面之前确实必须有$.ajax({ url: Api.GetMasterkey, dataType: 'json', data: { urlParamter:'' }, async: false, success: function (data) { /* This function is executed when data is received. Run ReactDOM.render from here, and pass data as a prop. */ } }); ,那么在使用React渲染任何内容之前,您必须进行API调用。想象一下,你的app有一个index.js或其他一些入口点,这通常是你调用ReactDOM.render()的地方。在此顶级文件中,执行API调用

getInitialState: function() {
  return {
    key: this.props.data // or whatever you call your prop
  };
}

在Page中,现在只需使用传递的道具来设置初始状态。

ContentA

一种不同的方法,如果ContentBcomponentDidMount可以处理暂时没有密钥的问题,就是在Page的setState函数中进行Ajax调用,然后调用{ {1}}在ajax函数中调用success函数时。

var Page = React.createClass({
  ...
  ...
  componentDidMount(){
    // Do Ajax stuff after the component has mounted
    var that = this;
    $.ajax({
        url: Api.GetMasterkey,
        dataType: 'json',
        data: {
            urlParamter:''
        },
        async: false,
        success: function (data) {
            // Change state after the data has been received.
            that.setState({
                key: data
            });
        }
    });
  }
  ...
  ...
  ...
})

现在,只要Api的回复准备就绪,渲染功能就会再次触发,而ComponentA和ComponentB可以通过引用this.state.key来使用密钥。

答案 1 :(得分:0)

var Page = React.createClass({
    getInitialState: function () {
        var masterKey = this.loadMasterKey();
        return { masterKey: masterKey };
    },
    getURLParameter: function (name) {        
        return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [, ""])[1].replace(/\+/g, '%20')) || null;
    },
    loadMasterKey: function () {
        var masterKey;
        $.ajax({
            url: Api.GetMasterkey,
            dataType: 'json',
            data: {
                id: this.getURLParameter('id'),
            },
            async: false,
            cache: false,
            success: function (data) {
                masterKey = data.SuccessPayLoad;
            }.bind(this),
            error: function (xhr, status, err) {
                console.error(xhr, status, err.toString());
            }.bind(this)
        });

        return masterKey;
    },
    componentDidMount: function () {
    },
    render: function () {
        return (
             <div>
                <Header />
                <Content masterKey={this.state.masterKey} />                 
                <Footer />
             </div>
        );
    }
});

module.exports = Page;

这是我的代码,页面是根组件。

你可以在函数getInitialState中看到我将发送给服务器的数据来自url(getInitialState函数)并且我将async设置为false。

我会将masterKey传递给子组件,例如Content和Content将使用此masterKey从服务器异步中获取数据。

我没有在Content中编写任何代码来在键返回之前处理异常。该计划现在运作良好但我应该处理