更新兄弟对象的反应

时间:2015-04-23 03:16:43

标签: reactjs

我正在学习反应,并想要实现一个基本的导航栏,其中包含一些项目,我想让我点击的最后一个让className处于活动状态,而其他所有项目都没有。

在下面的代码中,我无法使用item.setState删除resetALL中的className(是的,通过阅读我理解它不起作用的文档),所以我尝试使用jQuery直接操作dom。它适用于第一次单击,但第二次单击无效。是否有任何反应本地方式来做到这一点?谢谢。

    $(document).ready(function(){

        var NavItem = React.createClass({
            getInitialState: function() {
                return this.props.item;
            },

            handleClick: function() {
                React.render(<span>{this.props.item.description}</span>, document.getElementById('main'));

                this.props.resetALL();
                console.log("this", this);
                this.setState({active: true});
            },

            render: function() {
                var className = this.state.active ? "active" : "";
                return <li className={className}><a href="#" onClick={this.handleClick}>{this.props.item.description}</a></li>;
            }
        });

        var NavBar = React.createClass({
            items : [],

            resetALL: function() {
                this.items.forEach(function(item) {
                    console.log("item", item);
                    // item.setState({active: false});
                });

                $("#nav-sidebar li").each(function(){
                    $(this).removeClass("active");
                });
            },

            render: function() {
                var _this = this;

                this.props.items.forEach(function(item) {
                    console.log("handleClick", this.handleClick);
                    _this.items.push(<NavItem item={item} key={item.id} resetALL={_this.resetALL}/>);
                });

                return (
                    <ul className="nav nav-sidebar" id="nav-sidebar">
                        {this.items}
                    </ul>
                );
            }

        });


        var NAVLIST = [
            {id: 1, description: 'OverView', active: true},
            {id: 2, description: 'Calls'},
            {id: 3, description: 'Channels'},
            {id: 4, description: 'OverView'}
        ]

        React.render(<NavBar items = {NAVLIST} />, document.getElementById('sidebar'));


        React.render(
            <h1>Hello, FreeSWITCH!</h1>,
            document.getElementById('main')
        );

    });

3 个答案:

答案 0 :(得分:0)

environments { 'headless-ff' { driver = { pdriver = new PhantomJSDriver(new DesiredCapabilities()) pdriver.manage().window().maximize() pdriver } } } 调用NavItem时,该函数不会绑定到this.props.resetALL(),因此它无法遍历NavBar&#39}。的项目。您可以将它绑定到正确的范围,如下所示:

NavBar

答案 1 :(得分:0)

好吧,我看到你的代码中的一些东西在反应中有点不常见:

    每次发生事件时,
  • 重新呈现set "var=abc" set "var=123" & cmd /v /c"echo !var!" 元素有点会破坏react.js的目的。相反,您应该通过属性和事件进行沟通,并让main更新您想要的文字react
  • main不应负责设置其活动状态,NavItem是一个更合适的地方,因为它包含其他项目,并且可以轻松激活/停用所需的项目
  • 我建议将NavBar数组保存到items而不是成员变量,因为只要您想激活其他项目,只需更新状态
  • 推送state中的反应组件只是反应方式,您不需要直接存储和访问组件
  • 直接操作反应生成的DOM元素会干扰反应
  • 您也不需要_this.items.push

您可以在下面找到react.js解决问题的自然方法。这里要注意三件事:
1.数据下降,事件上升 2. $(document).ready()用于让反应知道某些事情发生了变化 3.有一个汇总setState组件可帮助您更新文本

App

答案 2 :(得分:0)

你是否对使用jQuery更新由React管理的DOM元素的类表示怀疑是正确的。每当React重新渲染时,您的jQuery更改通常会被覆盖。要好好使用React,你必须经常思考和重新思考你试图用你的应用程序表示的内容,以及定义其状态的数据应该自然存在的地方。

在此示例中,您尝试渲染导航链接列表,其中只有一个处于活动状态。 NavBar是一个更合理的存储项,它比NavItem的状态更活跃。

我建议将项目列表作为道具传递给NavList,并将最初活动的项目存储在NavList的状态中,或者将其作为清楚标记的initialActiveItem传递,如下所示:

<NavList items={NAVLIST} initialActiveItem={1} />

但是活动项的id应该存储在NavList的状态中,而不是props,所以这样做的一种方法是使用NavList的getInitialState生命周期方法来初始化活动项:

getInitialState: function() { return { activeItem: this.props.initialActiveItem }; },

当您需要更新活动项目时,例如在单击处理程序中,您可以使用setState调用,例如this.setState({activeItem: 2}

我在NavList上定义一个函数,它接受一个id并调用它的setState方法将活动项设置为该id,然后将该函数作为prop传递给每个项(在这一行中this是NavBar实例,itemthis.props.items)的一个元素:

<NavItem id={item.id} update={this.updateActive} key={item.id} active={this.state.activeId == item.id} />

NavItem只需要知道它的props.active是否为true以决定是否呈现活动className,以及如何将其id返回到NavBar的updateActive函数以使其自身处于活动状态(如果尚未激活) 。当NavBar更新时,它将重新渲染其子NavItems,并且它们将使用正确的活动状态进行更新,以便它们可以自己呈现正确的classNames。

当然,如果单击NavItems的目的不仅仅是更新该项是否处于活动状态,您还必须确保该单击会触发任何其他相关操作。如果这意味着更新完全不同的React组件的内容,比如您在#main中呈现的内容,请考虑您将存储和检索有关该其他组件中应包含内容的状态信息的位置。它可能应该是这两个元素的父级,或者是一些其他共享的有状态资源,如Flux Store。有关如何推断此信息所在位置的更多信息,请参阅https://facebook.github.io/react/blog/2013/11/05/thinking-in-react.html