Javascript React.js(传播事件和属性)中的动态子导航

Javascript React.js(传播事件和属性)中的动态子导航,javascript,reactjs,Javascript,Reactjs,在React.js中,我仍在努力解决的一件事是处理子事件和属性传播的正确方法。已经有很多这样的例子,但是实现方式总是大不相同。当然,有一种“正确的方法”可以做到这一点 任务是创建一个由“NavItem”组件组成的“Nav”组件。下面是我希望能够工作的代码,但它没有。这些评论解释了我的问题所在。请就最佳解决方案提出建议,并让我知道我做错了什么 Nav.jsx var Nav = React.createClass({ propTypes: { active:

在React.js中,我仍在努力解决的一件事是处理子事件和属性传播的正确方法。已经有很多这样的例子,但是实现方式总是大不相同。当然,有一种“正确的方法”可以做到这一点

任务是创建一个由“NavItem”组件组成的“Nav”组件。下面是我希望能够工作的代码,但它没有。这些评论解释了我的问题所在。请就最佳解决方案提出建议,并让我知道我做错了什么

Nav.jsx

var Nav = React.createClass({
    propTypes: {
        active:         React.PropTypes.string,
        onSelect:       React.PropTypes.func
    },
    getInitialState: function () {
        return {
            active: this.props.active
        };
    },
    render: function () {
        return this.transferPropsTo(
            <nav>
                {this.props.children.map(this.renderChild)}
            </nav>
        );
    },
    renderChild: function (child, i) {
        // Here I want to generate a unique 'key' property for each child as well
        // as define a custom onSelect method which will tell the "Nav" component which is
        // the active key.
        return React.addons.cloneWithProps(child, {
            // Here I want to use the 'active' property of the Nav component to drive the
            // the 'active' property of the child.
            active: this.state.active === i ? true, false,
            key: i,
            onSelect: this.handleSelect
        });
    },
    handleSelect: function (event, component) {
        // PROBLEM: Here I want to get the 'key' property of the child. But there seems to be
        // no way to do this.
        var _child_key_ = 'impossible'; 
        this.setState({active: _child_key_});
    }
});
var NavItem = React.createClass({
    propTypes: {
        active:     React.PropTypes.string,
        onSelect:   React.PropTypes.func
    },
    getInitialState: function () {
        return {
            active: this.props.active
        };
    },
    render: function () {
        return this.transferPropsTo(
            <a className="{this.state.active ? 'active' : ''}" onClick={this.handleSelect}>
                {this.props.label}
            </a>
        );
    },
    handleSelect: function (event, component) {
        // Propagate the event up to the parent event property.
        if (this.props.handleSelect) this.props.handleSelect(event, component);
    }
});
var App = React.createClass({
    render: function () {
        return (
            <Nav>
                <NavItem label="Home" />
                <NavItem label="Page1" />
                <NavItem label="Page2" />
            </Nav>
        );
    }
});

React.renderComponent(new App(), document.body)
var Nav=React.createClass({
道具类型:{
活动:React.PropTypes.string,
onSelect:React.PropTypes.func
},
getInitialState:函数(){
返回{
活动:this.props.active
};
},
渲染:函数(){
将此.transferPropsTo返回(
{this.props.children.map(this.renderChild)}
);
},
renderChild:函数(子级,i){
//在这里,我还想为每个孩子生成一个唯一的“key”属性
//定义一个自定义onSelect方法,该方法将告诉“导航”组件
//激活键。
返回React.addons.cloneWithProps(子{
//这里我想使用导航组件的“active”属性来驱动
//子对象的“活动”属性。
活动:this.state.active==i?true,false,
关键:我,,
onSelect:this.handleSelect
});
},
handleSelect:函数(事件、组件){
//问题:这里我想得到孩子的“key”属性,但似乎有
//没办法。
var _child _key=‘不可能’;
this.setState({active:_child_key});
}
});
NavItem.jsx

var Nav = React.createClass({
    propTypes: {
        active:         React.PropTypes.string,
        onSelect:       React.PropTypes.func
    },
    getInitialState: function () {
        return {
            active: this.props.active
        };
    },
    render: function () {
        return this.transferPropsTo(
            <nav>
                {this.props.children.map(this.renderChild)}
            </nav>
        );
    },
    renderChild: function (child, i) {
        // Here I want to generate a unique 'key' property for each child as well
        // as define a custom onSelect method which will tell the "Nav" component which is
        // the active key.
        return React.addons.cloneWithProps(child, {
            // Here I want to use the 'active' property of the Nav component to drive the
            // the 'active' property of the child.
            active: this.state.active === i ? true, false,
            key: i,
            onSelect: this.handleSelect
        });
    },
    handleSelect: function (event, component) {
        // PROBLEM: Here I want to get the 'key' property of the child. But there seems to be
        // no way to do this.
        var _child_key_ = 'impossible'; 
        this.setState({active: _child_key_});
    }
});
var NavItem = React.createClass({
    propTypes: {
        active:     React.PropTypes.string,
        onSelect:   React.PropTypes.func
    },
    getInitialState: function () {
        return {
            active: this.props.active
        };
    },
    render: function () {
        return this.transferPropsTo(
            <a className="{this.state.active ? 'active' : ''}" onClick={this.handleSelect}>
                {this.props.label}
            </a>
        );
    },
    handleSelect: function (event, component) {
        // Propagate the event up to the parent event property.
        if (this.props.handleSelect) this.props.handleSelect(event, component);
    }
});
var App = React.createClass({
    render: function () {
        return (
            <Nav>
                <NavItem label="Home" />
                <NavItem label="Page1" />
                <NavItem label="Page2" />
            </Nav>
        );
    }
});

React.renderComponent(new App(), document.body)
var NavItem=React.createClass({
道具类型:{
活动:React.PropTypes.string,
onSelect:React.PropTypes.func
},
getInitialState:函数(){
返回{
活动:this.props.active
};
},
渲染:函数(){
将此.transferPropsTo返回(
{this.props.label}
);
},
handleSelect:函数(事件、组件){
//将事件传播到父事件属性。
if(this.props.handleSelect)this.props.handleSelect(事件、组件);
}
});
MyApp.jsx

var Nav = React.createClass({
    propTypes: {
        active:         React.PropTypes.string,
        onSelect:       React.PropTypes.func
    },
    getInitialState: function () {
        return {
            active: this.props.active
        };
    },
    render: function () {
        return this.transferPropsTo(
            <nav>
                {this.props.children.map(this.renderChild)}
            </nav>
        );
    },
    renderChild: function (child, i) {
        // Here I want to generate a unique 'key' property for each child as well
        // as define a custom onSelect method which will tell the "Nav" component which is
        // the active key.
        return React.addons.cloneWithProps(child, {
            // Here I want to use the 'active' property of the Nav component to drive the
            // the 'active' property of the child.
            active: this.state.active === i ? true, false,
            key: i,
            onSelect: this.handleSelect
        });
    },
    handleSelect: function (event, component) {
        // PROBLEM: Here I want to get the 'key' property of the child. But there seems to be
        // no way to do this.
        var _child_key_ = 'impossible'; 
        this.setState({active: _child_key_});
    }
});
var NavItem = React.createClass({
    propTypes: {
        active:     React.PropTypes.string,
        onSelect:   React.PropTypes.func
    },
    getInitialState: function () {
        return {
            active: this.props.active
        };
    },
    render: function () {
        return this.transferPropsTo(
            <a className="{this.state.active ? 'active' : ''}" onClick={this.handleSelect}>
                {this.props.label}
            </a>
        );
    },
    handleSelect: function (event, component) {
        // Propagate the event up to the parent event property.
        if (this.props.handleSelect) this.props.handleSelect(event, component);
    }
});
var App = React.createClass({
    render: function () {
        return (
            <Nav>
                <NavItem label="Home" />
                <NavItem label="Page1" />
                <NavItem label="Page2" />
            </Nav>
        );
    }
});

React.renderComponent(new App(), document.body)
var-App=React.createClass({
渲染:函数(){
返回(
);
}
});
React.renderComponent(新应用程序(),document.body)

我相信这是最明智的方法

var Nav = React.createClass({
    propTypes: {
        active:         React.PropTypes.string,
        onSelect:       React.PropTypes.func
    },

    // no state
    //getInitialState: function () {},

    render: function () {
        // use React.Children.map because children is opaque
        return this.transferPropsTo(
            <nav>
                {React.Children.map(this.props.children, this.renderChild)}
            </nav>
        );
    },
    renderChild: function (child, i) {
        return React.addons.cloneWithProps(child, {
            // use the prop, not state
            active: this.props.active === i,
            key: i,

            // let the parent decide how to handle the data change
            // give it the clicked index
            onSelect: this.props.onSelect.bind(null, i)
        });
    }
});
var Nav=React.createClass({
道具类型:{
活动:React.PropTypes.string,
onSelect:React.PropTypes.func
},
//无州
//getInitialState:函数(){},
渲染:函数(){
//使用React.Children.map,因为子对象是不透明的
将此.transferPropsTo返回(
{React.Children.map(this.props.Children,this.renderChild)}
);
},
renderChild:函数(子级,i){
返回React.addons.cloneWithProps(子{
//使用道具,而不是状态
活动:this.props.active==i,
关键:我,,
//让父级决定如何处理数据更改
//给它一个点击的索引
onSelect:this.props.onSelect.bind(null,i)
});
}
});
var NavItem=React.createClass({
道具类型:{
//这是一个布尔值
活动:React.PropTypes.bool,
onSelect:React.PropTypes.func
},
//同样,没有国家
//getInitialState:函数(){},
渲染:函数(){
//只需直接传入onSelect处理程序
//让家长来处理
将此.transferPropsTo返回(
{this.props.label}
);
}
});
var-App=React.createClass({
getInitialState:function(){return{active:0}},
handleSelect:function(i){this.setState({active:i}}),
渲染:函数(){
返回(
);
}
});

没有真正的原因,至少在本例中,为什么不能将名为
onClick
的函数作为属性传递给
NavItem
,并让
NavItem
onClick
处理程序检查它是否存在(并且是一个funct)然后将事件作为第一个参数调用它,并将
this.props.key
作为第二个参数调用它。结果是您的
Nav
间接地处理了在您的
NavItem
中对
标记的点击,在您的用例中,您不需要使用
cloneWithProps
克隆子项,因为您只是传递道具。我需要为每个子项生成一个新的“活动”道具和一个新的“关键”道具。我发现唯一能把它传给孩子们的方法就是使用cloneWithProps。