- 此问题在此处已有答案**:
Lifting up state in React(3个答案)
4天前关闭。
这篇文章是4天前编辑并提交审查的。
让我开始给你一个提示,我是一个总noob在ReactJS。
我在nodejs中编写了登录页面的后端代码:
app.post("/login", (req, res) => {
const { username, pass } = req.body;
sqlLoginuser = "SELECT * FROM users WHERE username = ?"
db.query(sqlLoginuser, [username], (error, results) => {
if (error) throw error;
if (results.length === 0) {
return res.status(401).json({ message: "Username or password is incorrect" });
}
const user = results[0];
bcrypt.compare(pass, user.pass, (error, result) => {
if (error) throw error;
if (!result) {
return res.status(401).json({ message: "Username or password is incorrect" });
}
const token = jwt.sign({ userId: user.id }, JWT_SECRET, { expiresIn: "1h" });
res.status(200).json({
token,
isAdmin: user.is_admin,
message: "User logged in successfully",
});
});
}
);
});
我想在用户登录此登录页面后保存后端从数据库发送的isAdmin值:
import React, { useState } from "react";
import { useNavigate, Link } from "react-router-dom";
import axios from "axios";
import { toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import AuthContext from "./AuthContext";
const Login = () => {
const [isAdmin, setIsAdmin] = useState(false);
const [username, setUsername] = useState("");
const [pass, setPass] = useState("");
const navigate = useNavigate();
const handleSubmit = async (event) => {
event.preventDefault();
try {
const response = await axios.post("http://localhost:5000/login", {
username,
pass
});
toast.success("Te-ai logat cu succes")
localStorage.setItem("token", response.data.token);
setIsAdmin(response.data.isAdmin);
console.log(response.data.isAdmin);
navigate("/ip");
setTimeout(() => { window.location.reload() }, 2000);
} catch (error) {
toast.error(error.response.data.message);
// toast.error(error);
}
};
return (
<AuthContext.Provider value={{ isAdmin, setIsAdmin }}>
<div style={{ marginTop: "150px" }}>
<form style={{
margin: "auto",
padding: "15px",
maxWidth: "400px",
alignContent: "center"
}}
onSubmit={handleSubmit}>
<div>
<label htmlFor="username">Username:</label>
<input
type="text"
id="username"
placeholder="Username"
value={username}
onChange={(event) => setUsername(event.target.value)}
/>
</div>
<div>
<label htmlFor="password">Password:</label>
<input
type="password"
id="password"
placeholder="Password"
value={pass}
onChange={(event) => setPass(event.target.value)}
/>
</div>
<input type="submit" value={"Login"} />
<Link to="/register">
<input type="button" value="Fa-ti cont" />
</Link>
</form>
</div>
</AuthContext.Provider>
);
};
export default Login;
这样我以后就可以在其他页面中使用它的值,比如说在这个页面中:
import React, { useState, useEffect, useContext } from 'react';
import ReactPaginate from 'react-paginate';
import { Link } from 'react-router-dom';
import './home.css';
import { toast } from 'react-toastify';
import axios from 'axios';
import AuthContext from './AuthContext';
const IP = () => {
const isAdmin = useContext(AuthContext);
console.log("isAdmin:", isAdmin);
const [isLoading, setIsLoading] = useState(0);
const [data, setData] = useState([]);
const [currentPage, setCurrentPage] = useState(1);
const [totalPages, setTotalPages] = useState(1);
const itemsPerPage = 10;
const handleClick = () => {
setIsLoading(true);
// Make a request to the backend to extract the information and store it in a text file
axios.get("http://localhost:5000/extract-ip")
.then(response => {
if (response.status !== 200) {
throw new Error("Failed to extract data!");
}
const data = response.data;
const file = new Blob([data], { type: 'text/plain' });
const url = URL.createObjectURL(file)
const link = document.createElement('a');
link.href = url;
link.download = 'ip.txt';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
URL.revokeObjectURL(url);
setIsLoading(false);
})
.catch(error => {
console.error(error);
setIsLoading(false);
});
};
// code for fetching the users from the node.js backend to bring them to the frontend
const loadData = async () => {
const response = await axios.get(`http://localhost:5000/ip?page=${currentPage}`);
setData(response.data.data);
setTotalPages(response.data.totalPages);
};
useEffect(() => {
loadData();
});
const deleteIp = (id) => {
if (
window.confirm("Stergeti intrarea?")
) {
axios.delete(`http://localhost:5000/delete-ip/${id}`)
toast.success("Intrare eliminata cu succes!")
setTimeout(() => loadData(), 500);
}
}
const handlePageClick = (pageNumber) => {
setCurrentPage(pageNumber);
}
return (
<div style={{ marginTop: "50px" }}>
<Link to="/addIp">
<button className="btn btn-ip">Add IP</button>
</Link>
<table className='styled-table'>
<thead>
<tr>
<th style={{ textAlign: "center" }}>No.</th>
<th style={{ textAlign: "center" }}>IP address</th>
<th style={{ textAlign: "center" }}>Added on</th>
<th style={{ textAlign: "center" }}>Added by</th>
<th style={{ textAlign: "center" }}>Action</th>
</tr>
</thead>
<tbody>
{data.map((item, index) => {
const startIndex = (currentPage - 1) * itemsPerPage;
const rowNumber = startIndex + index + 1;
return (
<tr key={item.id}>
<th scope="row">{rowNumber}</th>
<td>{item.ip_address}</td>
<td>{item.creation_date.replace("T", " ").replace("Z", "").replace(".000", "")}</td>
<td>{item.published_by}</td>
<td>
{isAdmin === "1" ?
<>
<Link to={`/update-ip/${item.id}`}>
<button className="btn btn-edit">Edit</button>
</Link>
<button className="btn btn-delete" onClick={() => deleteIp(item.id)}>Delete</button>
<button className="btn btn-edit" disabled={isLoading} onClick={handleClick}>{isLoading ? "Loading..." : "Extract Data"}</button>
</>
:
<>
<Link to="/addIp">
<button className="btn btn-ip">Add IP</button>
</Link>
</>
}
</td>
</tr>
)
})}
</tbody>
</table>
<div className="pagination">
<ReactPaginate
pageCount={totalPages}
pageRangeDisplayed={5}
marginPagesDisplayed={2}
onPageChange={(data) => handlePageClick(data.selected + 1)}
containerClassName={"pagination"}
activeClassName={"active"}
/>
</div>
{/* <Link to="/">
<button className="btn btn-ip">Back</button>
</Link> */}
</div>
)
}
export default IP;
编辑:
我设法在Login.jsx中获得了这个值,但是当我试图将它传递到IP.jsx页面时,它没有得到更新。
当我登录时的输出:
console.log(isAdmin) is 1
但在IP页面中,输出为0。
为什么会这样?
1条答案
按热度按时间roejwanj1#
您可以使用context来实现这一点,但在尝试之前,您肯定需要了解如何使用props和state。
我建议您浏览react文档中的所有"Learn" sections。