反应路由器 - 将方法传递给子组件

React-Router - Pass Method to Child Component

本文关键字:组件 方法 路由器      更新时间:2023-09-26

>我有一个嵌套在名为"Create"的组件中的按钮,该按钮必须触发状态更改,从而更改应用程序中的状态.js并呈现一个新视图。

我似乎无法将方法更改HPage从应用程序.js传递到创建组件。我正在使用 React-Router,通常我会简单地编写<App changeHPage={this.changePage}>将方法传递给其子组件并使用 this.props.changeHpage 调用它,但在使用 React Router 时我无法通过此方法传递 props。

有关如何使用 React Router 将方法传递给子组件的任何帮助将不胜感激。我的代码可以在下面找到。

应用.js:

    /* STRICT MODE: See `../../server.js` */
'use strict';
/* GLOBAL REACT REQUIRES */
// React.js
const React = require('react');
// React-DOM for HTML rendering
const ReactDOM = require('react-dom');
// React router for dynamic pathing. Has several component features that need to be required to use.
const ReactRouter = require('react-router');
// 4 components pulled from ReactRouter:
const Router = ReactRouter.Router;
const Route = ReactRouter.Route;
const Navigation = ReactRouter.Navigation;
const Link = ReactRouter.Link;
const browserHistory = ReactRouter.browserHistory;
/* Relative paths to external components */
const auth = require('./helpers/auth.js');
const requireAuth = require('./helpers/requireauth.js');
const About = require('./components/about.js');
const Login = require('./components/login.js');
const Logout = require('./components/logout.js');
const Signup = require('./components/signup.js');
const Header = require('./components/header.js');
const Create = require('./components/create.js');
const NotFound = require('./components/notfound.js');
const Veri = require('./components/veri.js');

/* React App Creation */
const App = React.createClass({
  // Declares the initial state when app is loaded
  getInitialState : function() {
    return {
      loggedIn: auth.loggedIn(),
      change: true,
      phoneNumber: {}
    }
  },
  // Updates state when login is trigger
  updateAuth : function(loggedIn) {
    this.setState({
      loggedIn: loggedIn
    })
  },

  changeHPage: function() {
    this.state.change = !this.state.change;
    this.setState({
      change: !this.state.change
    });
    console.log("changePage On HomePage Pressed");
    this.context.router.push('/')
  },


  // Login even triggered and sent to back-end
  componentWillMount : function() {
    auth.onChange = this.updateAuth
    auth.login()
  },

  addNumber: function(phonenumber){
    this.state.phonenumber = phonenumber
    this.setState()
  },

  // Renders App and all of its children
  render : function() {
    <div className="Detail">
        {this.props.children && React.cloneElement(this.props.children, {
          changeHPage: this.changeHPage
        })}
      </div>
    var firstView;

      {if(this.state.change) {
        firstView = <div>
      <div className="row">
      <Veri> This is a child of Veri </Veri>
      <Header details="Hi, I'm Plantee"/>
        <section className="col s12">
        <ul>
            {this.state.loggedIn ? (
              <div>
                <li><Link to="/logout">Log out</Link> </li>
                <li><Link to="/create">Create Your Plantee</Link></li>
                {/*<Create> <Veri/> </Create>*/}
             </div>
            ) : (
              <div>
                <li><Link to="/login">Log In</Link></li>
                <li><Link to="/signup">Sign up</Link></li>
             </div>
            )}
          <li><Link to="/about">About</Link></li>
        </ul>
        {this.props.children || <p>You are {!this.state.loggedIn && 'not'} logged in.</p>}
        </section>
      </div> </div>
    } else {
      firstView= <div>'Hello'</div>
    }
      return React.cloneElement(
        firstView,
        {switch: this.changeHPage}
      )
  }}
})


/* React router initialization */
var routes = (
  <Router history={browserHistory}>
    <Route path="/" component={App} >
    <Route path="header" component={Header} />
      <Route path="login" component={Login} />
      <Route path="logout" component={Logout} />
      <Route path="create" component={Create} change={App.changeHPage} />
      <Route path="signup" component={Signup} />
      <Route path="about" component={About} />
      <Route path="very" component={Veri} />
    </Route>
    <Route path="*" component={NotFound} />
  </Router>
)
ReactDOM.render(routes, document.querySelector('#container'))

创建.js:

const React = require('react');
const ReactDOM = require('react-dom');
const auth = require('../helpers/auth')
const Veri = require('./veri.js');
const App = require('../app.js');
const ReactRouter = require('react-router');
// 4 components pulled from ReactRouter:
const Router = ReactRouter.Router;
const Route = ReactRouter.Route;
const Navigation = ReactRouter.Navigation;
const Link = ReactRouter.Link;
const browserHistory = ReactRouter.browserHistory;

const Create = React.createClass({
  getInitialState: function(){
    return {checked: false}
  },
  handleClick: function(event) {
    event.preventDefault();
    this.setState({checked: !this.state.checked})
    let phonenumber = {
      phonenumber: this.refs.phonenumber.value
    }
  },
  showVerification : function(event) {
    event.preventDefault();
  },

  remove(e) {
    e.preventDefault();
    console.log(this.props);
  },
  render : function(){
    var msg;
    {if(this.state.checked) {
      msg = <div><Veri text={'Your verification code is '}  code={'code'}/> <form className="gotIt" onSubmit={this.props.changeHpage} >
      <input type="Submit" value="Got It" />
       </form> </div>
    }
    else {
      msg = <Veri details={''}/>
    }}
    return (
      <div>
      <h1>Create Your Plantee</h1>
      <h2>Please Enter Your Phone Number</h2>
      <p>You will recieve a phone call in order to verify that you are capable of raising a plantee</p>

      <form className="telephoneNumber" onSubmit={this.handleClick}>
         <input id="phonenumber" ref="phonenumber" type="tel" />
         <input type="Submit" />
       </form>
       <div> {msg} </div>
       <h3>{this.props.children}</h3>

       </div>
    )
  }
})
module.exports = Create;

请参阅以下 github 问题:https://github.com/reactjs/react-router/issues/1857这直接取自:瑞安弗洛伦斯

通常,如果您跨路由边界传递道具,则父路由确切地知道它在渲染什么:

<Route path="/inbox" component={Inbox}>
  <Route path=":messageId" component={Message}/>
  <IndexRoute component={InboxStats}/>
</Route>
const Inbox = React.createClass({
  render() {
    return (
      <div>
        {/* this is only ever `Message`, except the weird case
          of `InboxStats` which doesn't need the prop */}
        {React.cloneElement(this.props.children, {
          onDelete: this.handleMessageDelete
        })}
      </div>
    )
  }
})

相反,使用无组件路由,只做"普通"的 React 事情。

<Route path="/inbox" component={Inbox}>
  {/* no more `Message` */}
  <Route path=":messageId"/>
</Route>
const Inbox = React.createClass({
  render() {
    const { messageId } = this.props.params
    return (
      <div>
        {messageId ? (
          <Message onDelete={this.handleMessageDelete}/>
        ) : (
          <InboxStats/>
        )}
      </div>
    )
  }
})

cloneElement 本身并不是一个坏做法,但它通常可以表明有更直接的方法来做某事。