如何将组件引用传递给react中的routes组件

时间:2018-03-31 06:18:20

标签: javascript html css reactjs redux

在反应中,我想将组件的引用传递给路由组件。但是当我路由到诸如'/'之类的路径时,它会重新渲染传递的组件,所以再次从0开始。 这是一个工作示例链接 https://codesandbox.io/s/884yror0p2 这是一个代码,每当我从Home路由时 - >关于about计数器从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"));

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

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. 使用Route的{​​{3}}属性传入任何props
  2.   

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

    1. 使用render的功能版本来引用prevState