Home > Blockchain >  React, page cannot get parameter for URL to redirect
React, page cannot get parameter for URL to redirect

Time:10-02

I'm a beginner, and new to React. When I retrieve data from the database with the id value as the parameters in the URL, it doesn't get the parameter, so not directed to the right page.

This is the screenshot just by using the button. The "id" in the URL didn't have a value. :id didn't change to the parameter

If manually type in a parameter, the URL may work. manually type the parameter

Here are my codes below.

Server part in server.js to query database

// VIEW ACCOUNT
app.get("/profile/:id", (req, res) => {
    const {id} = req.params;
    database.query(
        "SELECT * FROM users WHERE id = ?;",
        id,
        (err, result) => {
            if (err) {
                console.log(err);
            } else {
                res.send(result);
            }
        });
})

Client part in component Sidebar.js to redirect to profile page by URL with parameter

function Sidebar(){
    let navigate = useNavigate();
    ......
    ......
    const routeProfile = () =>{
        let path = `/profile/:id`;
        navigate(path);
    }

    const routeLogout = () => {
        let path = "/login";
        navigate(path);
    }

    return (
        <div className="sidebar grid-1">
            <button className="blue_bt option_list round bt_width mb" onClick={routeCourse}>Courses</button>
            <button className="yellow_bt option_list round bt_width mb" onClick={routeStudent}>Students</button>
            <button className="purple_bt option_list round bt_width mb" onClick={routeSchedule}>Schedule</button>
            <button className="green_bt option_list round bt_width mb bottom" onClick={routeProfile}>Profile</button>
            <button className="red_bt option_list round bt_width mb bottom" onClick={routeLogout}>Log out</button>
        </div>
    )
}

Client part in page component Profile.js to contact back end

function Profile() {
    let navigate = useNavigate();

    const [user, setUser] = useState({});
    const {id} = useParams();

    useEffect(() => {
        axios.get(`http://localhost:3001/profile/${id}`).then((response) => {
            setUser(response.data[0]);
            console.log(response.data[0]);
    })},[id]);
    ......
    ......
    return (
        <div className="grid-container">
            <Sidebar/>
            <div className="main_content grid-2">
                <div className="details">
                    <div className="icon" style={{color: "#27c200"}}>
                        <FontAwesomeIcon icon="user"/> HELLO
                        <div className="back-button" onClick={() => navigate(-1)}>
                            <FontAwesomeIcon icon="arrow-alt-circle-left"/>BACK
                        </div>
                    </div>
                    <div className="detail-content">
                        <h1 style={{fontSize: "45px"}}>{user.fname}</h1>
                        <h2 style={{fontSize: "30px", marginTop: "-0.1em"}}>{user.lname}</h2>
                        <div className="break-line"></div>
                        <div>
                            <h2 style={{fontSize: "20px"}}>
                                Email: <span style={{color: "#27c200"}}>{user.email}</span>
                            </h2>
                            <h2 style={{fontSize: "20px"}}>
                                Phone: <span style={{color: "#27c200"}}>{user.phone}</span>
                            </h2>
                            <h2 style={{fontSize: "20px"}}>
                                UID: <span style={{color: "#27c200"}}>{user.id}</span>
                            </h2>
                            <button className="green_bt option_list round mr" onClick={user}>Edit
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    )
}

Can anyone help me figure out where the problem is?

CodePudding user response:

From your screenshot, I guess that you want to write a dynamic path to navigate different profiles so your code should be

const routeProfile = (id) =>{
        let path = `/profile/${id}`;
        navigate(path);
    }

Here your id should be dynamic and you will get this id in the Profile component when you call the useParams() hook if your Route path is written correctly.

CodePudding user response:

I think this depends on how and what you use in your app. The most obvious cause of the issue is that you're using "/profile/:id" as the route to navigate to. So, unless you're doing some custom handling of the string in the function returned by your useNavigate hook, the behaviour should be expected.

You should ask yourself, when the line navigate(path) runs, with the path equal to "/profile/:id"/, whose profile should the user be shown? If the id of the user is 32, then the user should be shown the profile of the user with the id of 32. This can only be achieved by making the user navigate to "/profile/32" as opposed to "/profile/:id"/ when the button is clicked.

For this, you would need to know the id of the user before hand, and also have access to it in your component. This may be by storing the id in sessionStorage or cookies when the user logs in. And if you have a root component that renders all of your pages (in case of a full-fledged single page app), you might want to store the id of the user as a state in that root component and pass it to your page components as a prop. By doing that, you would have to handle the user id only in the root component, set it to a number if a user is logged in, or null otherwise.

I would love to give code examples, but I'm writing this answer on a mobile phone, so that's not possible.

Bear in mind, the "/profile/:id" is handled specially by Express. It tells Express that every single endpoint in that form (/profile/ followed by some other value that don't alter the meaning of the url should all trigger your callback, and that Express should make the "some other value" accessible in your callback which you have accessed as req.params.id. This allows you to capture all /profile/_id_ requests in that single route. If that wasn't possible, you'll have to write app.get for every single one of your users based on their id.

Once you have the user id, you can call your navigate function like this:

const path = `/profile/${savedID}`;
navigate(path);

Note the use of string template literals. The value of savedID here would be the id passed down from your root component, or that which you've read from sessionStorage, cookies, or some other storage option. (You may also hard code some value for testing.)

I hope this helps...

  • Related