【问题标题】:React state passing through children and passing back to parent反应状态通过子级并传回父级
【发布时间】:2022-01-06 13:29:38
【问题描述】:

我确信有类似的问题,我曾尝试对此进行研究,但非常令人困惑。我正在为 Web 应用程序创建登录页面。我有一个包含用户名、密码和用户位置的数据库。用户将登录并被发送到其职位的页面。但是我正在使用 react-router-dom 并且如果用户位置不正确,我想创建一个重定向但是我似乎无法传递在登录页面中设置的状态

对于我的登录页面login.jsusernamepasswordposition 都是状态,position 是在服务器返回一个真值声明和用户position 时设置的。然后我需要将它传回我的App.js,其中包含路由器和路由,从login.js 传回的位置现在可用于验证用户是否可以访问该页面。

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

登录.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>
    
    )
}

【问题讨论】:

    标签: javascript reactjs state react-props


    【解决方案1】:

    好的,将数据从子级传递给父级和另一个子级不是您应该考虑的方法。

    每当您发现自己处于这种情况时,请不要将状态存储在 Child 中,将“状态”向上移动以存储在 parent 中,如果孩子需要,您可以通过 props 将该状态传递给 Child(登录页面)数据。

    但是

    在这种特殊情况下,不要忘记 React-router 也可以存储一个“状态”(url + url param + 甚至是一个状态)

    在您的情况下,将“位置”存储在反应路由器状态中是最有意义的。

    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 ...*/ }
            });
        }
    
    

    您可以使用useLocationuseParams 来读取这些值。

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

    【讨论】:

      猜你喜欢
      • 2016-09-29
      • 2022-08-04
      • 2020-06-22
      • 1970-01-01
      • 1970-01-01
      • 2020-10-05
      • 2020-09-09
      • 2016-11-03
      • 1970-01-01
      相关资源
      最近更新 更多