每次任何组件更新(包括路由更改)时调用函数

时间:2016-09-30 10:04:08

标签: reactjs

是否可以在React更新中每次任何时调用一个函数?

更多背景信息: 我想在React中使用EQCSS的全部功能。我已经尝试了2个NPM包,但它们似乎没有按照我的预期完成。

我想做的是,每次任何组件更新时,我都想致电componentDidUpdate

我尝试过调用import React from "react"; import ReactDOM from "react-dom"; import { Router, Route, browserHistory } from "react-router"; import { MainLayout } from "./layouts"; import { HomePage, RankingsPage } from "./routes"; class App extends React.Component { render() { return ( <Router history={browserHistory}> <Route component={MainLayout}> <Route path="/" component={HomePage} /> <Route path="/rankings" component={RankingsPage} /> </Route> </Router> ); } componentDidUpdate() { console.log("COMPONENT UPDATED"); // This does not get called when changing pages. } } // Render the main component into the dom ReactDOM.render(<App />, document.getElementById("app")); ,但在更改页面时(例如使用react-router),这似乎不起作用。

<PolyStyle>
 <Fill>0</Fill>
 <Outline>1</Outline>
</PolyStyle>

2 个答案:

答案 0 :(得分:1)

感谢@ VishnuShekhawat的link,显示我在错误的地方等待componentDidUpdate()功能。 将其更改为MainLayout组件,并在页面/路由更改时调用它。

答案 1 :(得分:1)

以下是三种不同的方法:

  1. 反应背景

    1. MutationObserver
    2. 将您的主要母组件包裹在MutationObserver中。更多信息:

      MutationObserver将跟踪实际 DOM树的任何更改。

      1. 回调函数通过道具
      2. 我在这里展示了另一种方法:https://codepen.io/PiotrBerebecki/pen/wzqQkx。请检查每次在页面上发生某些事情时记录消息的控制台,包括路由更改,或深层嵌套子组件的重新呈现。然而,这依赖于通过props传递到子层次结构的回调。

        广告1.语境演示代码:

        class App extends React.Component {
          static childContextTypes = {
            data: React.PropTypes.bool
          };
        
          getChildContext() {
            return {data: true};
          }
          render() {
            return (
              <div>
                <h1>Parent</h1>
                <Child />
              </div>
            )
          }
        }
        
        
        class Child extends React.Component {       
          static contextTypes = {
            data: React.PropTypes.bool
          };
        
          render() {
            console.log('in Child', this.context.data)
            return (
              <div>
                <h3>Child</h3>
                <Grandchild />
              </div>
            );
          }
        }
        
        
        class Grandchild extends React.Component {       
          static contextTypes = {
            data: React.PropTypes.bool
          };
        
          render() {
            console.log('in Grandchild', this.context.data)
            return (
              <div>
                <h6>Grandchild</h6>
              </div>
            );
          }
        }
        
        
        ReactDOM.render(
          <App />,
          document.getElementById('app')
        );
        

        广告3.回调演示代码:

        var MainLayout = React.createClass({
          doSomething: function() {
            console.log('something happened');
          },
        
          render: function() {
            this.doSomething();
            const childrenWithProps = React.Children.map(this.props.children,
             (child) => React.cloneElement(child, {
               doSomething: this.doSomething
             })
            );
        
            return (
              <div className="app">
                <header className="primary-header"></header>
                <aside className="primary-aside">
                  <ul>
                    <li><Link to="/">Home</Link></li>
                    <li><Link to="/users">Users</Link></li>
                    <li><Link to="/widgets">Widgets</Link></li>
                  </ul>
                </aside>
                <main>
                  {childrenWithProps}
                </main>
              </div>
              )
          }
        })
        
        var Home = React.createClass({
          getInitialState: function() {
            return {
              counter: 1
            };
          },
        
          componentDidUpdate: function() {
            this.props.doSomething()
          },
        
          changeCounter: function() {
            this.setState({
              counter: this.state.counter + 1
            });
          },
        
          render: function() {
            return (
              <div>
                <button onClick={this.changeCounter}>Click me</button>
                <br />
                {this.state.counter}
              </div>
            );
          }
        })
        
        var SearchLayout = React.createClass({
          render: function() {
            const childrenWithProps = React.Children.map(this.props.children,
              (child) => React.cloneElement(child, {
               doSomething: this.props.doSomething
             })
            );
        
            return (
              <div className="search">
                <header className="search-header"></header>
                <div className="results">
                  {childrenWithProps}
                </div>
                <div className="search-footer pagination"></div>
              </div>
              )
          }
        })
        
        var UserList = React.createClass({
          getInitialState: function() {
            return {
              counter: 1
            };
          },
        
          componentDidUpdate: function() {
            this.props.doSomething()
          },
        
          changeCounter: function() {
            this.setState({
              counter: this.state.counter + 1
            });
          },
        
          render: function() {
            return (
              <div>
                User List
                <br />
                <button onClick={this.changeCounter}>Click me</button>
                <br />
                {this.state.counter}
              </div>
            );
          }
        });
        
        var WidgetList = React.createClass({
          getInitialState: function() {
            return {
              counter: 1
            };
          },
        
          componentDidUpdate: function() {
            this.props.doSomething()
          },
        
          changeCounter: function() {
            this.setState({
              counter: this.state.counter + 1
            });
          },
        
          render: function() {
            return (
              <div>
                Widgets
                <br />
                <button onClick={this.changeCounter}>Click me</button>
                <br />
                {this.state.counter}
              </div>
            );
          }
        })
        
        
        
        ReactDOM.render((
          <Router>
            <Route path="/" component={MainLayout}>
              <IndexRoute component={Home} />
              <Route component={SearchLayout}>
                <Route path="users" component={UserList} />
                <Route path="widgets" component={WidgetList} />
              </Route> 
            </Route>
          </Router>
        ), document.getElementById('root'))