将状态从一个组件传递到另一个无状态组件

时间:2019-08-02 11:53:15

标签: reactjs react-router react-router-dom

我试图在下面的代码中总结我的问题。我的实际代码太大,因此我开发了另一种类似的代码来解决此问题。 我有一个登录页面,用户必须在其中输入“ True”或“ False”来更新此组件的状态。 我需要将此状态传递给“ Route”组件,该组件将验证将要呈现的页面。如果从登录组件收到的参数为“ True”,则将显示主页。如果为“ False”,将显示登录页面。

根据我的理解,我必须将道具从childreen传递给父组件,但是我无法解决此问题。

App.jsx(组件)

import React from 'react'
import { BrowserRouter } from 'react-router-dom'
import Routes from './Routes'

export default props =>
    <BrowserRouter>
        <div>
            <Routes />
        </div>    
    </BrowserRouter>

Routes.jsx(组件)

import React from 'react'
import { Switch, Route, Redirect} from 'react-router'
import Login from './Login';
import Home from './Home';

const PrivateRoute = ({ component: Component, ...rest }) => (
    <Route
        {...rest}
        render={props =>
            isAuthenticated() ? (
                <Component {...props} />
            ): (
                <Redirect to={{pathname: "/login", state: {from: props.location }}} />
            )}
    />
)

const Routes = () =>
    <Switch>
        <PrivateRoute path='/home' component={Home} />
        <Route exact path='/login' component={Login} />
        <Redirect from='*' to='/home' />
    </Switch>

export default Routes;

Home.jsx(组件)

import React, { Component } from 'react'

export default class Home extends Component {
    render (){
        return (
            <h1>This is the HOME page</h1>
        );
    }
}

Login.jsx(组件)

import React, { Component } from 'react'
import { Link } from 'react-router-dom'
import Routes from './Routes'

export default class Login extends Component{

    constructor(props){
        super(props);
        this.state = {
            userLoggedIn: false
        }
        this.handleChange = this.handleChange.bind(this)
    }

     handleChange(e) {
        e.preventDefault()
        let stateName = e.target.name
        let stateValue = e.target.value
        console.log(e.target, e.target.value)
        this.setState({ [stateName]: stateValue})
    }

    render(){
        console.log('esse estado é',this.state.userLoggedIn)
        return( 
            <div>
                <div>This is the Login Page</div>
                <label>State Test</label>
                <input placeholder="true or false" onChange={e => this.handleChange(e)}></input>
                <Link to={{pathname: "/home"}}>
                    <button >Go To Home Page</button>
                </Link>
            </div>   
        )        
    }
}

我期望什么? 当用户在“登录”页面中键入“ True”时,必须呈现主页。 当用户在“登录”页面中键入“ False”时,必须呈现“登录”页面。

1 个答案:

答案 0 :(得分:1)

这是工作代码,codesandbox link

如果用户输入false,则不会重定向他,因为他已经在Login页面上。

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

function AuthExample() {
  return (
    <Router>
      <div>
        <AuthButton />
        <ul>
          <li>
            <Link to="/home">Home Page</Link>
          </li>
        </ul>
        <Route path="/login" component={Login} />
        <PrivateRoute path="/home" component={Home} />
      </div>
    </Router>
  );
}

const fakeAuth = {
  isAuthenticated: false,
  authenticate(cb) {
    this.isAuthenticated = true;
    setTimeout(cb, 100); // fake async
  },
  signout(cb) {
    this.isAuthenticated = false;
    setTimeout(cb, 100);
  }
};

const AuthButton = withRouter(({ history }) =>
  fakeAuth.isAuthenticated ? (
    <p>
      Welcome!{" "}
      <button
        onClick={() => {
          fakeAuth.signout(() => history.push("/"));
        }}
      >
        Sign out
      </button>
    </p>
  ) : (
    <p>You are not logged in.</p>
  )
);

function Home() {
  return <h3>This is the HOME page</h3>;
}

function PrivateRoute({ component: Component, ...rest }) {
  return (
    <Route
      {...rest}
      render={props =>
        fakeAuth.isAuthenticated ? (
          <Component {...props} />
        ) : (
          <Redirect
            to={{
              pathname: "/login",
              state: { from: props.location }
            }}
          />
        )
      }
    />
  );
}

class Login extends Component {
  state = {
    redirectToReferrer: false,
    input: ""
  };

  login = e => {
    e.preventDefault();
    if (this.state.input === "true") {
      fakeAuth.authenticate(() => {
        this.setState({ redirectToReferrer: true });
      });
    } else {
      this.setState({ redirectToReferrer: true });
    }
  };

  handleChange = ({ target }) => {
    this.setState({ [target.name]: target.value });
  };

  render() {
    let { from } = this.props.location.state || { from: { pathname: "/" } };
    let { redirectToReferrer } = this.state;

    if (redirectToReferrer) return <Redirect to={from} />;

    return (
      <div>
        <div>This is the Login Page</div>
        <label>State Test</label>
        <br />
        <input
          placeholder="true or false"
          name={"input"}
          value={this.state.input}
          onChange={this.handleChange}
        />
        <br />
        <button onClick={this.login}>Go To Home Page</button>
      </div>
    );
  }
}

export default AuthExample;

希望有帮助!

相关问题