【问题标题】:How to pass component reference to routes component in react如何在反应中将组件引用传递给路由组件
【发布时间】:2018-03-31 06:18:19
【问题描述】:

在反应中,我想将组件的引用传递给路由组件。但是当我路由到诸如“/”之类的路径时,它会重新渲染传递的组件,因此再次从 0 开始。 这是工作示例的链接 https://codesandbox.io/s/884yror0p2 这是一个代码,每当我从主页路由时-->关于计数器从 0 开始。

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";

class Dummy extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      c: 0
    };
    setInterval(() => {
      this.setState({ c: this.state.c + 1 });
    }, 1000);
  }

  render() {
    return <h1> Counter {this.state.c}</h1>;
  }
}

class BasicExample extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      // com: <Dummy /> this technique also not work
    };
  }
  render() {
    let com = <Dummy />;
    return (
      <div>
        <Router>
          <div>
            {com}
            <ul>
              <li>
                <Link to="/">Home</Link>
              </li>
              <li>
                <Link to="/about">About</Link>
              </li>
            </ul>

            <hr />
            <Route
              exact
              path="/"
              // render={() => <Home com={com} />} //this also not work
              component={props => <Home {...props} com={com} />}
            />
            <Route path="/about"
              component={props => <About {...props} com={com} />}             
             />
          </div>
        </Router>
      </div>
    );
  }
}

class Home extends React.Component {
  render() {
    return (
      <div>
        {this.props.com}
        <h2>Home </h2>
      </div>
    );
  }
}

class About extends React.Component {
  constructor(props) {
    super(props);
    console.log(this.props);
  }
  render() {
    return (
      <div>
        {this.props.com}
        <h2>About</h2>
      </div>
    );
  }
}

ReactDOM.render(<BasicExample />, document.getElementById("root"));

【问题讨论】:

  • 根据这个计数器的含义,最好用redux解决。虚拟组件的实例化是什么样的事件?使用 redux,您可以通过 mapStateToProps 将计数器传递给任何连接的组件并通过操作增加它。

标签: javascript html css reactjs redux


【解决方案1】:

您不能通过“引用”传递组件。但是,如果您希望在所有组件之间拥有相同的数据,您可以在父组件 (BasicExample) 中初始化您的状态并将其向下传递或使用像 Redux 这样的状态容器。

【讨论】:

    【解决方案2】:

    您可以关闭组件,但组件也将经历一个挂载过程,这将使您存储在其中的状态无效。 如果你需要保持状态,它应该存储在父组件中。

    const Router = ReactRouterDOM.HashRouter;
    const Route = ReactRouterDOM.Route;
    const Link = ReactRouterDOM.Link;
    
    class Dummy extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          c: props.c || 0
        };
      }
      componentWillReceiveProps(nextProps) {
        if (this.props.c !== nextProps.c) {
          this.setState({
            c: nextProps.c
          });
        }
      }
      render() {
        return <h1> Counter {this.state.c}</h1>;
      }
    }
    
    class BasicExample extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          counter: 0
        };
        setInterval(() => {
          this.setState(prevState => {
            return {
              counter: prevState.counter + 1
            };
          });
        }, 1000);
      }
      render() {
        let Com = <Dummy c={this.state.counter} />;
        return (
          <div>
            <h2>Main App</h2>
            <Router>
              <div>
                {Com}
                <ul>
                  <li>
                    <Link to="/">Home</Link>
                  </li>
                  <li>
                    <Link to="/about">About</Link>
                  </li>
                </ul>
    
                <hr />
                <Route
                  exact
                  path="/"
                  // render={() => <Home com={com} />} //this also not work
                  render={props => (
                    <Home {...props} c={this.state.counter} Com={Dummy} />
                  )}
                />
                <Route
                  path="/about"
                  render={props => (
                    <About {...props} c={this.state.counter} Com={Dummy} />
                  )}
                />
              </div>
            </Router>
          </div>
        );
      }
    }
    
    class Home extends React.Component {
      render() {
        const Com = this.props.Com;
        return (
          <div>
            <h2>Home </h2>
            <Com c={this.props.c} />
          </div>
        );
      }
    }
    
    class About extends React.Component {
      constructor(props) {
        super(props);
      }
      render() {
        const Com = this.props.Com;
        return (
          <div>
            <h2>About</h2>
            <Com c={this.props.c} />
          </div>
        );
      }
    }
    
    ReactDOM.render(<BasicExample />, document.getElementById("root"));
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-router/4.2.0/react-router.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-router-dom/4.2.2/react-router-dom.js"></script>
    <div id="root"></div>

    这里有几点需要注意:

    1. 使用Routerender 属性传入任何props

    当你使用组件(而不是渲染或子,下面) 路由器使用 React.createElement 从 给定的组件。这意味着如果您向 组件道具,您将在每次渲染时创建一个新组件。这 导致现有组件卸载和新组件 安装而不是仅仅更新现有组件。使用时 用于内联渲染的内联函数,使用 render 或 儿童道具

    1. 使用setState的函数版本引用prevState

    【讨论】:

      猜你喜欢
      • 2020-03-26
      • 1970-01-01
      • 2015-09-01
      • 2016-05-26
      • 2016-09-30
      • 1970-01-01
      • 2023-03-25
      • 2018-04-15
      • 1970-01-01
      相关资源
      最近更新 更多