简体   繁体   English

React state 通过孩子并传回给父母

[英]React state passing through children and passing back to parent

I am sure there are similar questions and I have tried to research this but it was very confusing.我确信有类似的问题,我曾尝试对此进行研究,但这很令人困惑。 I am creating a login page for a web application.我正在为 web 应用程序创建登录页面。 I have a database that holds a username, password and a users position.我有一个包含用户名、密码和用户 position 的数据库。 A user will login and be sent to the page of their position.用户将登录并被发送到其 position 的页面。 However I am using react-router-dom and I want to create a redirect if the users position isn't right however I can't seem to pass a state that is set in the login page但是我正在使用 react-router-dom 并且如果用户 position 不正确,我想创建一个重定向但是我似乎无法通过在登录页面中设置的 state

For my login page login.js , the username , password and the position are all states, the position is set when the server responds back with a truth statement and the users position .对于我的登录页面login.jsusernamepasswordposition都是状态,当服务器返回真值语句和用户positionposition I then need to pass this back to my App.js which contains the router and routes, the position that was passed back from the login.js can now be used to authenticate that the user can go to that page.然后,我需要将其传递回包含路由器和路由的App.js ,从login.js传回的 position 现在可用于验证用户是否可以 go 访问该页面。

App.js应用程序.js

// import { io } from "socket.io-client";
import Login from "./Components/Login"
import {BrowserRouter, Routes, Route} from "react-router-dom"
import Admin from "./Components/Admin"


function App() {
  // const socket = io("http://192.168.1.179:3001");

  // socket.on("connect", () => {
  //   console.log(socket.id);
  // });

  // socket.on("disconnect", () => {
  //   console.log(socket.id);
  // });

  return (
  <>
      <BrowserRouter>
        <Switch>
          <Routes>
            <Route path="/" element={<Login/>} />
            <Route path="/admin" element={<Admin />}/>
          </Routes>
        </Switch>
      </BrowserRouter>
    
  </>)
}

export default App;

Login.js登录.js

import React,{useState,useEffect, useRef} from 'react'
import {Button, Card, Form, FormLabel, Modal} from 'react-bootstrap'
import axios from "axios"
import Admin from './Admin'

export default function Login() {
    // User States
    const [username,setUsername] = useState("")
    const [password, setPassword] = useState("")
    const [position, setPosition] = useState("")

    // Modal State and Functions
    const [showModal, setShowModal] = useState(false);

    const handleCloseModal = () => setShowModal(false);
    const handleShowModal = () => setShowModal(true);

    const [message,setMessage] = useState("")

    //handleSubmit
    function submit(e){
        e.preventDefault()
        handleShowModal()
        login()
        handleCloseModal()
    }

    function incorrectUsername(){
        setMessage("Username Doesn't Exist!")
        setUsername("")
        setPassword("")
    }

    function incorrectPassword(){
        setMessage("Incorrect Password!")
        setPassword("")
    }

    function handleCorrectResponse(passedPosition){
        setMessage("Correct Username and Password")
        setPosition(passedPosition)
        
    }

    //handleLogin
    async function login(){
        await axios.get("http://0.0.0.0:3001/api/login", {params:{"username":username,
        "password":password}}).then((response)=>{
            if (response.data.key === 0){
                incorrectUsername()
            }
            else if(response.data.key === 1){
                incorrectPassword()
            }
            else if(response.data.key === 2){
                handleCorrectResponse(response.data.position)
            }
            else{
                setMessage("ERROR!")
            }
        })
    }

    // Page Rendering
    return (
        <div style={{
            display:"flex",
            justifyContent: "center",
            alignItems: "center",
            minHeight:"100vh"
            }}>
                {position}
            <Card style={{
                height:"450px",
                width:"400px",
                display:"flex",
                borderRadius:"10%"}}>
                <Card.Title style={{textAlign:"center",paddingTop:"15%"}}>
                    <h1>Login</h1>
                </Card.Title>
                <Card.Body >
                    <p style={{color:"red",textAlign:"center"}}>{message}</p>
                    <Form onSubmit={submit} >
                        <div style={{paddingBottom:"10%"}}>
                            <FormLabel>Username:</FormLabel>
                            <Form.Control onChange={(e)=>{
                                setUsername(e.target.value)
                            }} type="text" required value={username}/>
                        </div>
                        <div style={{paddingBottom:"10%"}}>
                            <FormLabel>Password:</FormLabel>
                            <Form.Control onChange={(e)=>{
                                setPassword(e.target.value)
                            }} type="password" required value={password}/>
                        </div>
                        <Button variant="primary" type="submit">Log In</Button>
                    </Form>
            
                    

                </Card.Body >
            </Card>

            {/* Modal */}
            <Modal
            backdrop = "static"
            keyboard = {false}
            show={showModal}
            onHide={handleCloseModal}
            aria-labelledby="contained-modal-title-vcenter"
            centered
            >
                <Modal.Title style={{padding:"5% 5%"}}>
                    Logging In...
                </Modal.Title>
            </Modal> 
        </div>
    
    )
}

Ok, passing data from Children to Parent and to another Children is not the approach you should be looking at.好的,将数据从子级传递给父级和另一个子级不是您应该考虑的方法。

Whenever you find yourself in this situation, don't store state in the Child, move the "state" up to store in parent, and you can pass that state to Child (login page) via props if the child need that data.每当您发现自己处于这种情况时,不要将 state 存储在 Child 中,将“状态”向上移动以存储在 parent 中,如果孩子需要该数据,您可以通过 props 将该 state 传递给 Child(登录页面)。

BUT

In this particular case, don't forget that React-router can store a "state" too (url + url param + or even a state)在这种特殊情况下,不要忘记 React-router 也可以存储“状态”(url + url 参数 + 甚至是状态)

In your case, it would make most sense to store "position" in react router state.在您的情况下,将“位置”存储在反应路由器 state 中最有意义。

const history = useHistory();

function handleCorrectResponse(passedPosition){
        setMessage("Correct Username and Password")
        history.push({
          pathname: '/' // <--- url you want to go
          search: { /*... value(state) you want to show in url ... */},
          state: { /*...value(state) you don't want to show in url ...*/ }
        });
    }

And you can use useLocation , useParams to read those value.您可以使用useLocationuseParams来读取这些值。

read more here https://v5.reactrouter.com/web/api/history在这里阅读更多https://v5.reactrouter.com/web/api/history

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM