React-Router - 将方法传递给子组件

时间:2016-03-19 15:26:47

标签: javascript reactjs react-router

我有一个嵌套在名为" Create"的组件中的按钮。必须触发状态更改,以更改app.js中的状态并呈现新视图。

我似乎无法将方法changeHPage从app.js传递给Create组件。我正在使用React-Router,通常我只需编写<App changeHPage={this.changePage}>将方法传递给它的子组件并使用this.props.changeHpage调用它,但在使用React Router时我无法通过此方法传递道具。

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

app.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'))

create.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;

1 个答案:

答案 0 :(得分:0)

请参阅以下github问题: https://github.com/reactjs/react-router/issues/1857 这直接取自:ryanflorence

通常,如果您在路线边界上传递道具,则您的父路线确切知道它的渲染内容:

<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本身并不是一种糟糕的做法,但它通常可以表明有一种更直接的做法。