【问题标题】:How to structure react app to render components properly?如何构建反应应用程序以正确呈现组件?
【发布时间】:2017-09-25 05:43:59
【问题描述】:

当用户在我的应用中创建任务时,我想显示一条信息性消息。我已经在 react 中工作了一段时间,但是我无法想到显示一次后消失的消息的逻辑。

这是当前设置

App.js 使用 react router dom 路由到不同页面的主要组件,如下所示:

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      taskCreated: false,
    };
  }

  showTaskCreatedAlert = () => {
    this.setState({ taskCreated: true });
  };

  render() {
    return (
        <Router>
          <div>
            <Switch>
              <Route 
                exact 
                path="/" 
                component={props => <TasksIndex {...this.state} />} 
              />
              <Route
                path="/users/new"
                component={props => (
                  <TasksNew
                    showTaskCreatedAlert={this.showUserCreatedAlert}
                    {...props}
                  />
                )}
              />
            </Switch>
          </div>
        </Router>
    );
  }
}

TasksNew.js 呈现用户可以创建任务的表单的组件

成功创建任务后,我会更新父组件(App.js 的状态并将 taskCreated 设置为 true。然后将历史记录推送到根资源“/”。

TasksIndex.js 呈现用户创建的所有任务的组件 该组件获取作为 props 传递给它的主要组件状态,并且根据 taskCreated 设置为 true 还是 false,它将显示该信息性消息

一切都很好,除了用户导航到 /users/new 并返回后消息不会消失。只有在完全重新加载时它才会消失。现在我知道为什么会这样了:父组件的状态永远不会更新,并且 taskCreated 保持为真。

但是如何做到这一点呢?一旦用户导航到应用程序中的不同页面,如何让消息消失。我想在没有 redux 的情况下完成这个。

【问题讨论】:

  • 我认为这个链接会帮助你解决问题。 How to Pass variable to parent component
  • 首先,使用 Route 的“render”道具而不是“组件”。其次,不知道你是否可以使用TasksIndex的componentWillUnmount将taskCreated设置回false?

标签: reactjs react-router


【解决方案1】:

您需要的只是在任何应用程序路由更改后将父组件的状态 taskCreated 更改为 false。您可以通过订阅浏览器历史记录来做到这一点:

import createBrowserHistory from 'history/createBrowserHistory'

const history = createBrowserHistory()

class App {
    constructor(props) {
         super(props);
         this.state = {
             taskCreated: false,
         };
    }

    showTaskCreatedAlert = () => {
         this.setState({ taskCreated: true });
    };

    componentDidMount() {
         // listen for changes of location
         this.unlisten = history.listen((location, action) => {
              this.setState({ taskCreated: false });
         });
    }
    componentWillUnmount() {
         // Remove your listener when your component is destroyed
         this.unlisten();
    }
    render() {
        <Router history={history}>
            // ...
        </Router>
    }
}

【讨论】:

  • 我的应用组件永远不会卸载。只有内部组件安装/卸载。你也不应该在 componentWillUnmount 中调用 setState。
  • 在卸载组件时移除任何监听器是一个很好的做法,即使您的应用还没有这个用例。 “history.listen”调用将返回一个取消订阅函数并将其设置为 this.unlisten 属性。后来,在组件卸载中“this.unlisten()”正在删除一个历史监听器,它不会调用setState。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-04
  • 2018-02-01
  • 2021-11-11
  • 2012-08-04
相关资源
最近更新 更多