gpt4 book ai didi

reactjs - 当 Prop 更改时, react meteor 数据容器不会更新子级

转载 作者:行者123 更新时间:2023-12-03 13:39:04 24 4
gpt4 key购买 nike

我已经为这个问题苦苦挣扎了很长一段时间,但未能找到任何答案。

我使用 react-meteor-data 来管理我的 meteor 应用程序中的数据。它在处理 mongo 数据时工作正常,但我无法使其与 props 发生 react 。

App.js中,我调用我的容器,当应用程序的状态发生变化时,我希望它能够响应并重新渲染。

<MyContainer someState={this.state.MyState} />

MyContainer.js中,我有一个来自react-meteor-datacreateContainer

export default createContainer(params => {
Meteor.subscribe('someCollection');

return {
someCollection: SomeCollection.find({}).fetch(),
stateFromParent: params.someState
};
}, MyContainer);

第一次渲染组件时效果很好,MyContainer正确获取MyState

问题是,当 App 中的 MyState 发生变化时,我可以在 Chrome Dev React 工具中看到它确实针对 createContainer 进行了更新>( ReactMeteorDataComponent 有一个具有正确更新状态的 prop),但 createContainer 函数未运行,因此 props 不会更新 我的容器

因此,props 是从 ReactMeteorDataComponent 更新的,但对于无限期保留数据的 MyContainer 则不然。就像 createContainer 不认为其 prop 的更新发生了变化,因此不运行其函数。

我真的认为我错过了一些东西,因为这似乎是非常基本的东西,谢谢您的帮助。

最佳答案

OP没有提到状态是如何改变的,所以原始的例子是不完整的。因此,我将尝试解释容器创建的原理,希望对理解它有所帮助。

<小时/>

它是如何工作的?

当其计算无效时(即,当 react 性数据源之一(例如 react 性变量、订阅句柄或获取的 MiniMongo 游标)具有新值时),它使用 Meteor 的 Tracker 自动更新包装的组件。要了解有关 Tracker 的更多信息,请参阅 Tracker manual 。这是一个深入的资源,不需要了解基础知识的工作原理。

它的执行方式与您通常在 Meteor 中进行 react 性跟踪的方式不同,因为每当容器的 props 发生更改时,它也需要重新运行计算。

源代码不是很长或复杂,可以在 GitHub 上找到(当前为 here )。

  Tracker.autorun((c) => {
if (c.firstRun) {
//...
data = component.getMeteorData();

} else {
// Stop this computation instead of using the re-run.
// We use a brand-new autorun for each call to getMeteorData
// to capture dependencies on any reactive data sources that
// are accessed. The reason we can't use a single autorun
// for the lifetime of the component is that Tracker only
// re-runs autoruns at flush time, while we need to be able to
// re-call getMeteorData synchronously whenever we want, e.g.
// from componentWillUpdate.
c.stop();
// Calling forceUpdate() triggers componentWillUpdate which
// recalculates getMeteorData() and re-renders the component.
component.forceUpdate();
}
})

每当计算无效(并因此重新运行)时,它都会停止计算并强制重新渲染容器,这将重新创建新的计算并具有更新的数据。

高级容器功能在这里(为简洁起见,删除了一些部分):

export const ReactMeteorData = {
componentWillMount() {
this.data = {};
this._meteorDataManager = new MeteorDataManager(this); // (1)
const newData = this._meteorDataManager.calculateData(); // (2)
this._meteorDataManager.updateData(newData); // (3)
},

componentWillUpdate(nextProps, nextState) {
// backup current state and props, assign next ones to components
let newData = this._meteorDataManager.calculateData(); // (2)
this._meteorDataManager.updateData(newData); // (3)
// restore backed up data
},

componentWillUnmount() {
this._meteorDataManager.dispose(); // (4)
},
};

要点是:- 在安装之前,会创建一个新的数据管理器(1)。它负责运行计算并根据数据变化填充this.data。- 首先,每当组件应该更新时,都会运行计算(2)并更新数据(3)。每当组件接收到新的状态或属性(在这种类型的容器中,它应该只是属性)时,就会发生更新,并且,正如我们之前所见,当 Tracker 计算由于调用 组件而无效时,也会发生更新。强制更新()

包装的组件接收父级的 props,以及 Tracker 计算的数据作为 props:

return <WrappedComponent {...this.props} {...this.data} />;
<小时/>

关于如何使用它还有更多要点吗?

react-meteor-data 有一个 short section在 meteor 指南中。

一般来说,指南中的简单示例(以及OP的示例)应该可以正常工作,只要使用setState()正确设置状态(请参阅“如何它有效吗?”上面的部分)。

此外,无需将容器状态重新映射到发送给子级的 props,因为它们会被传递(除非有充分的理由这样做)。

请考虑 preventing re-renders 中的要点如果您遇到任何性能问题,请参阅部分。

来自指南:

export default ListPageContainer = withTracker(({ id }) => {
const handle = Meteor.subscribe('todos.inList', id);
const loading = !handle.ready();
const list = Lists.findOne(id);
const listExists = !loading && !!list;
return {
loading,
list,
listExists,
todos: listExists ? list.todos().fetch() : [],
};
})(ListPage);

在此示例中,请注意容器需要一个 id 属性,并且它也可供包装的组件使用,以及 loading list 等(来自示例中容器的计算)。

关于reactjs - 当 Prop 更改时, react meteor 数据容器不会更新子级,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45127565/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com