如何在反应中将组件引用传递给路由组件 [英] How to pass component reference to routes component in react

查看:43
本文介绍了如何在反应中将组件引用传递给路由组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

从react"导入React;从react-dom"导入 ReactDOM;从react-router-dom"导入{ BrowserRouter 作为路由器、路由、链接};class Dummy 扩展了 React.Component {构造函数(道具){超级(道具);this.state = {时间:0};setInterval(() => {this.setState({ c: this.state.c + 1 });}, 1000);}使成为() {返回<h1>计数器 {this.state.c}</h1>;}}class BasicExample 扩展 React.Component {构造函数(道具){超级(道具);this.state = {//com: <Dummy/>这种技术也行不通};}使成为() {让 com = <Dummy/>;返回 (<div><路由器><div>{com}<ul><li><链接到="/">主页</链接><li><Link to="/about">关于</Link><小时/><路线精确的路径=/"//render={() =><Home com={com}/>}//这也不行组件={道具=><Home {...props} com={com}/>}/><路线路径=/关于"组件={道具=><关于 {...props} com={com}/>}/>

</路由器>

);}}class Home 扩展 React.Component {使成为() {返回 (<div>{this.props.com}<h2>首页 </h2>

);}}class 关于扩展 React.Component {构造函数(道具){超级(道具);console.log(this.props);}使成为() {返回 (<div>{this.props.com}<h2>关于</h2>

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

解决方案

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

const Router = ReactRouterDOM.HashRouter;const Route = ReactRouterDOM.Route;const Link = ReactRouterDOM.Link;class Dummy 扩展了 React.Component {构造函数(道具){超级(道具);this.state = {c: props.c ||0};}componentWillReceiveProps(nextProps) {如果 (this.props.c !== nextProps.c) {this.setState({c: nextProps.c});}}使成为() {返回<h1>计数器 {this.state.c}</h1>;}}class BasicExample 扩展 React.Component {构造函数(道具){超级(道具);this.state = {计数器:0};setInterval(() => {this.setState(prevState => {返回 {计数器:prevState.counter + 1};});}, 1000);}使成为() {让 Com = <Dummy c={this.state.counter}/>;返回 (<div><h2>主应用程序</h2><路由器><div>{com}<ul><li><链接到="/">主页</链接><li><Link to="/about">关于</Link><小时/><路线精确的路径=/"//render={() =><Home com={com}/>}//这也不行渲染={道具=>(<Home {...props} c={this.state.counter} Com={Dummy}/>)}/><路线路径=/关于"渲染={道具=>(<关于{...props} c={this.state.counter} Com={Dummy}/>)}/>

</路由器>

);}}class Home 扩展 React.Component {使成为() {const Com = this.props.Com;返回 (<div><h2>首页 </h2><Com c={this.props.c}/>

);}}class 关于扩展 React.Component {构造函数(道具){超级(道具);}使成为() {const Com = this.props.Com;返回 (<div><h2>关于</h2><Com c={this.props.c}/>

);}}ReactDOM.render(, 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. 使用 render 属性的 Route 传入任何 props

<块引用>

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

  1. 使用setState 的函数版本来参考 prevState

In react i want to pass a reference of component to routes component . But when i route to path such as '/' it re render the passed component so starts with 0 again. Here is a Link of Working example https://codesandbox.io/s/884yror0p2 Here is a code, whenever i route from Home-->About the about counter starts with 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"));

解决方案

You can the component down but the component will also go through a mounting process that will invalidate the state that you have stored in it. If you need to hold the state, it should be stored in the parent component.

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>

Few things to note here are:

  1. Use render property of Route to pass in any props

When you use component (instead of render or children, below) the router uses React.createElement to create a new React element from the given component. That means if you provide an inline function to the component prop, you would create a new component every render. This results in the existing component unmounting and the new component mounting instead of just updating the existing component. When using an inline function for inline rendering, use the render or the children prop

  1. Use function version of setState to refer to prevState

这篇关于如何在反应中将组件引用传递给路由组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆