在Ajax加载元素之前,ReactJs尝试附加onclick处理程序

时间:2015-06-19 07:27:40

标签: javascript ajax reactjs

我正在为ReactJs中的菜单创建动态列表。每个菜单项的数据都是通过AJAX从JSON文件中提取的。我希望在单击菜单项时关闭菜单。当点击其中一个菜单项时,我给整个列表提供了“whenClicked”。以下是代码:

var MenuList = React.createClass({
    getInitialState: function() {
        return {data: []}
    },
    componentWillMount: function() {
        $.ajax({
            url: 'http://10.0.0.97:8888/public-code/data/data.json',
            dataType: 'json',
            success: function(data) {
                this.setState({data: data});
            }.bind(this),
            error: function(xhr, status, error) {
                var err = JSON.parse(xhr.responseText);
                console.log(err.Message);
            }
        });
    },
    render: function() {
        var list = this.state.data.map(function(menuItemProps) {
            return <MenuItem onClick={this.props.whenClicked} {...menuItemProps} key={menuItemProps.id} />
        });
        return (
            <ul id="menu-list">
                {list}
            </ul>
        )
    }
});

然后,“whenClicked”prop会在父菜单中触发一个名为“handleClick”的函数,该函数会更改菜单的状态并在菜单打开时将其关闭。以下是父菜单组件的代码,其中包含上面的MenuList组件:

module.exports = React.createClass({

    getInitialState: function() {
        return {open: false, mobi: false}
    },
    handleClick: function() {
        this.setState({open: !this.state.open})
    },
    closeOnMobiScroll: function() {
        /*
        if(this.state.mobi === false) {
            this.setState({open: false})
        }
        */
    },
    updateDimensions: function() {
        $(window).width() >= 767 ? this.setState({mobi: true}) : this.setState({mobi: false});
    },
    componentWillMount: function() {
        this.updateDimensions();
    },
    componentDidMount: function() {
        $(window).on("resize", this.updateDimensions);
    },
    componentWillUnmount: function() {
        $(window).on("resize", this.updateDimensions);
    },
    render: function() {
        return (

            <div id="menu" className={(this.state.open ? 'open' : '')} >
                <div id="menu-inner-wrap">
                    <MenuTitle />
                    <MenuToggle whenClicked={this.handleClick}/>
                    <MenuList whenClicked={this.handleClick}/>
                </div>
            </div>

        )
    }

});

问题是整个脚本在AJAX调用触发之前中断,我收到以下错误:

Uncaught TypeError: Cannot read property 'whenClicked' of undefined

由于我在控制台中没有看到我的AJAX“失败”消息,我怀疑问题是React正在尝试连接

onClick={this.props.whenClicked}

我的数据加载之前。

有没有办法解决这个问题?还有其他我想念的东西吗?

2 个答案:

答案 0 :(得分:1)

该问题与Ajax调用或React无关。

在传递给.map的回调中,this指的是全局对象不是组件。全局对象没有prop属性,因此出错。

您可以使用.bind将函数的this值绑定到组件:

this.state.data.map(function(...) { ... }.bind(this));

更多信息:How to access the correct `this` context inside a callback?

答案 1 :(得分:1)

看起来你需要绑定映射函数的正确上下文。尝试:

var list = this.state.data.map( function(menuItemProps) {
    return <MenuItem onClick={this.props.whenClicked} {...menuItemProps} key={menuItemProps.id} />
}.bind(this) );