【问题标题】:Reactjs children not created in render don't update未在渲染中创建的 Reactjs 子项不会更新
【发布时间】:2014-04-10 16:24:07
【问题描述】:

React 组件包含子组件的标准方法是在 render 方法中创建它们并设置为 children 属性。在我的用例中,可以在渲染父级之前创建子级并通过父级的属性传入。

子中的事件按预期冒泡到父容器,但对父容器的更改不会重新渲染以这种方式创建的子容器。 The docs 表示父关系和所有者关系之间存在差异,后者仅针对在渲染中创建的组件建立,所以我的猜测是这种关系缺失并且对于级联重新渲染很重要。

这是一个简单的例子 (fiddle)

 /** @jsx React.DOM */

globalState = 'initial state';

var Child = React.createClass({
    render: function() {
        return React.DOM.input({
            value:globalState
        });
    }
});

var Parent = React.createClass({
    handleChange: function(e) {
        globalState = e.target.value;
        this.forceUpdate();
    },
    render: function() {
        return React.DOM.div({
            children: [
                Child(),
                React.DOM.br(),
                this.props.passedChild
            ],
            onChange: this.handleChange
        });
    }
});

c = Child();
p = Parent({passedChild:c});

React.renderComponent(p, document.body);

在这个例子中,两个子输入都可以被编辑,onChange 事件被父捕获并调用 forceUpdate()。这确实会级联到在渲染方法中创建的第一个孩子,但不会级联到在其他地方创建并传入的第二个孩子。

如何更新子组件的所有者,以便它根据需要进行更新?

我的备用计划是在子组件上连接一个事件监听器。在我的应用程序中,当创建组件时有相当多的逻辑,这使得在 render() 中执行所有操作变得不切实际。

【问题讨论】:

    标签: reactjs


    【解决方案1】:

    这里解释起来有点复杂,但您的代码现在可以在 React 的主版本(0.10.0 后)上运行。

    我不太确定您要在这里完成什么,但是如果您将 this.props.passedChild 更改为 this.props.passedChild() 并将 c = Child(); 更改为 c = Child;,它将起作用。称它为this.props.passedChildClass 或其他名称。你也可以试试this.props.passedChildFnc = function() { return Child(); }。满足您的需求。

    不要创建组件的实例并传递它(这不会很快成为大问题;Child() 的返回值将不再是实例)。一般来说,这是不好的做法,因为这会鼓励突变。根据需要即时创建您的孩子,让 React 处理其余的事情。

    在我的应用程序中,当创建组件时存在相当多的逻辑,这使得在 render() 中执行所有操作变得不切实际。

    将它们分解为辅助函数!你真的不必把所有东西都塞进一个render

    另外,全局状态是个坏主意。您的孩子通过阅读globalState 正确更新这一事实非常脆弱。您必须在控制台中收到警告(前提是您使用的是开发版本)才能添加 onChange 处理程序。去读吧=)。

    【讨论】:

    • 示例代码是对真实代码的过度简化,因此您提出的更改并不是那么简单,但感谢您确认这将解决我的问题。它实际上在 0.8.0 中工作,并且仅在升级到 0.10.0 时才观察到,很高兴听到这种行为又回来了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-01
    • 2017-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-05
    相关资源
    最近更新 更多