gpt4 book ai didi

javascript - react + Alt : Lifecycle Gap

转载 作者:行者123 更新时间:2023-11-30 00:19:53 25 4
gpt4 key购买 nike

编辑:查看 git 存储库中的最小示例: https://github.com/maximilianschmitt/blind-lifecycle

我有一个组件 RequireUser 试图确保用户已登录,否则不会呈现其子项。它的父组件 App 应该知道是否需要用户并在需要时呈现登录表单。

问题是,App 组件在 RequireUser 组件之后挂载在树中,如下所示:

App
RequireUser
SomeOtherComponent

RequireUsercomponentDidMount 中,我正在触发一个操作 requireLogin 来设置 UserStore >loginRequired 变量为 true

这不会更新父组件 (App),因为它尚未安装,因此无法将更改注册到商店。

class RequireUser extends React.Component {
constructor() {
super();
this.state = alt.stores.UserStore.getState();
}

componentDidMount() {
this.unlisten = alt.stores.UserStore.listen(this.setState.bind(this));
if (!this.state.requireUser) {
UserActions.requireUser();
// using setTimeout will work:
// setTimeout(() => UserActions.requireUser());
}
}

componentWillUnmount() {
this.unlisten();
}

render() {
if (this.state.requireUser) {
return <div>I have required your user</div>;
}

return <div>I will require your user</div>;
}
}

class App extends React.Component {
constructor() {
super();
this.state = alt.stores.UserStore.getState();
}

componentDidMount() {
this.unlisten = alt.stores.UserStore.listen(this.setState.bind(this));
}

componentWillUnmount() {
this.unlisten();
}

render() {
return (
<div>
<div>User required? {this.state.requireUser + ''}</div>
<RequireUser />
</div>
);
}
}

输出:

User required? false

I have required your user

如果我在 RequireUser 中使用 setTimeoutApp 会收到状态更改并呈现,但仅在闪烁之后:

User required? true

I have required your user

我觉得我正在做的是一种反模式,如果有比使用 setTimeout 闪烁更优雅的解决方案的建议,我将不胜感激。谢谢!

最佳答案

我建议的答案是将其添加到 App 组件中:

componentDidMount() {
// setup listener for subsequent changes
alt.stores.UserStore.listen(this.onChange);

// grab the current state now that we're mounted
var userStoreState = alt.stores.UserStore.getState();
this.setState(userStoreState);
}

没有办法避免双重渲染。您的 RequireUser 组件已经执行了两次渲染。

  1. RequireUser 的初始渲染
  2. componentDidMount() 回调
    • 一个 Action 被调度
  3. UserStore 接收分派(dispatch)的操作并更新其状态
    • 发出更改通知
  4. RequireUser 根据状态变化设置状态
  5. RequireUser 的第二次渲染

但是您的代码库仍然被认为是 Flux,并且确实遵循了用于 React 应用程序的模式。本质上,你有一个加载状态......我们实际上不知道是否需要用户的状态。根据 UserActions.requireUser() 的作用,这可能需要也可能不需要。

您可能会考虑重构

如果将 RequireUser 重写为仅查看组件,则可以修复双重呈现。这意味着没有听众,也没有内部设置状态。该组件只是根据传入的 props 渲染元素。这实际上是您的 RequireUser 组件的所有内容:

class RequireUser extends React.Component {
render() {
if (this.props.requireUser) {
return <div>I have required your user</div>;
}
return <div>I will require your user</div>;
}
}

然后您将使您的 App 组件成为一个controller-view。在这里添加了监听器,状态的任何变化都通过 props 向下传播。现在我们可以在 componentWillMount 回调中设置。这为我们提供了单一渲染行为。

class App extends React.Component {
(other lifecycle methods)

componentWillMount() {
if (!this.state.requireUser) {
UserActions.requireUser();
}
var userStoreState = alt.stores.UserStore.getState();
this.setState(userStoreState);
}

componentDidMount() {
(same as above)
}

render() {
return (
<div>
<div>User required? {this.state.requireUser + ''}</div>
<RequireUser requireUser={this.state.requireUser} />
</div>
);
}
}

Flux 架构和 Controller View / View :https://facebook.github.io/flux/docs/overview.html#views-and-controller-views

关于javascript - react + Alt : Lifecycle Gap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33550763/

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