【问题标题】:Pass state from one component to another stateless component将状态从一个组件传递到另一个无状态组件
【发布时间】:2019-12-11 01:16:27
【问题描述】:

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

据我了解,我必须将道具从子组件传递给父组件,但我无法解决这个问题。

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”时,必须呈现登录页面。

【问题讨论】:

  • 您可能希望使用 redux 来存储您的登录信息并根据其状态渲染组件
  • 参考这个exampleisAuthenticated方法定义在哪里?
  • @Jose - 我已经添加了答案,如果这对你有用,请告诉我。
  • @tarzenchugh 对迟到的回复感到抱歉。感谢您的回答....我理解您的回答,尽管我无法解决我的问题...我已经为此苦苦挣扎了好几个星期。无论如何,谢谢。

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


【解决方案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;

希望对你有帮助!!!

【讨论】:

    猜你喜欢
    • 2020-03-12
    • 1970-01-01
    • 1970-01-01
    • 2018-09-28
    • 1970-01-01
    • 2021-01-11
    • 2018-03-07
    • 2018-02-19
    • 2021-03-01
    相关资源
    最近更新 更多