Home > Software design >  Failed to get state by useLocation while it has Object data in state
Failed to get state by useLocation while it has Object data in state

Time:10-26

First.js

import { useState } from "react";
import { Link } from "react-router-dom";



const First = () => {
    
    const [name, setName] = useState("");
    const [phone, setPhone] = useState("");

    const handleSubmit = (e) => {
        e.preventDefault();
    }

    return ( 
        <div className="First">
            <h1>This is First Input Page</h1>
            <form onSubmit={handleSubmit}>
                <dd>data 1</dd>
                <input
                    type="text" 
                    value={name} 
                    onChange={(e) => 
                        setName(e.target.value)
                    }
                    required
                ></input>
                <dd>data 2</dd>
                <input
                    type="text" 
                    value={phone} 
                    onChange={(e) => 
                        setPhone(e.target.value)
                    }
                    required
                ></input><br/>
                <Link to={'/second'} state={{ state: { name : name , phone : phone } }}><button>submit</button></Link>
            </form>
        </div>
     );
}
 
export default First;

I try to send Object data using Link/state to another component.

Second.js

import {useLocation} from 'react-router-dom';



const Second = () => {
    const location = useLocation();
    
    console.log(location.state);
    console.log(location.state.name);


    return ( 
        <div className="Second">
            <h1>This is Second Input Page</h1>
            <form>
                <dd>data 3</dd>
                <input></input>
                <dd>data 4</dd>
                <input></input><br/>
                <button>submit</button>
            </form>
        </div>
     );
}
 
export default Second;

However, while I can access to (location.state), I can not access to (location.state.name). Why is that?

Output

state: {name: 'Myname', phone: 'myphone'}

[[Prototype]]: Object

--------------------

undefined

The output shows that the code line "console.log(location.state);" works, but to the "console.log(location.state.name);", it shows undefined.

CodePudding user response:

It's because you passed an object with state as the root property, i.e.

state={{ state: { name: name, phone: phone } }}

so to access it in the receiving route it is location.state.state.name.

You really don't need to nest the data you want to pass under a state property when using the Link component, it's not quite the same as when using the navigate function.

<Link to="/second" state={{ name, phone }}>
  <button>submit</button>
</Link>

It may also be considered semantically incorrect HTML to nest a button element within an anchor tag (via Link) element. Use the useNavigate hook and issue an imperative navigation action from the form's submit handler. In this case the navigate function's second argument, the options object, *does* expect the state to be passed under the state` property.

Example:

import { Link, useNavigate } from "react-router-dom";

const First = () => {
  const navigate = useNavigate();

  const [name, setName] = useState("");
  const [phone, setPhone] = useState("");

  const handleSubmit = (e) => {
    e.preventDefault();
    navigate("/second", { state: { name, phone } });
  };

  return ( 
    <div className="First">
      <h1>This is First Input Page</h1>
      <form onSubmit={handleSubmit}>
        <dd>data 1</dd>
        <input
          type="text" 
          value={name} 
          onChange={(e) => 
            setName(e.target.value)
          }
          required
        />
        <dd>data 2</dd>
        <input
          type="text" 
          value={phone} 
          onChange={(e) => 
            setPhone(e.target.value)
          }
          required
        />
        <br/>
        <button>submit</button>
      </form>
    </div>
  );
};
 
export default First;
  • Related