1

I have 2 pages: (Datatable.jsx and Single.jsx).

I need to send id from Datatable.jsx to Single.jsx. After googling, i found that i can do that by using the <Link /> component, like this:

<Link
  to={{
    pathname: "/page",
    state: data
  }}
>

And then you can access the desired sent data to the second page:

render() {
  const { state } = this.props.location
  return (
    // render logic here
  )
}

I dont know how to apply this on my two pages:

Datatable.jsx:

//...

const Datatable = () => {
  const [data, setData] = useState([]);

  const handleDelete = (id) => {
    setData(data.filter((item) => item.id !== id));
    fetch(`https://api.factarni.tn/article/${id}`, {
      method: "DELETE",
      headers: {
        Authorization:
          "Bearer eyJhbGciOiJS...qw2QWltkyA",
      },
    }).then((response) => response.json());
  };

  useEffect(() => {
    fetch("https://api.factarni.tn/article", {
      method: "GET",
      headers: {
        Authorization:
          "Bearer eyJhbGciOiJSUz...WltkyA",
      },
    })
      .then((response) => response.json())
      .then((json) => setData(json));
  }, []);

  const actionColumn = [
    {
      field: "action",
      headerName: "Action",
      width: 200,
      renderCell: (params) => {
        return (
          <div className="cellAction">
            <Link to="/users/test" style={{ textDecoration: "none" }}>
              <div className="viewButton">Modifier</div>
            </Link>
            <div
              className="deleteButton"
              onClick={() => handleDelete(params.row.id)}
            >
              Delete
            </div>
          </div>
        );
      },
    },
  ];
  return (
    <div className="datatable">
      <div className="datatableTitle">
        Add New Article
        <Link to="/users/new" className="link">
          <AddBusinessIcon className="icon" /> Add Article
        </Link>
      </div>
      <DataGrid
        className="dataGrid"
        rows={data}
        columns={userColumns.concat(actionColumn)}
        pageSize={9}
        rowsPerPageOptions={[9]}
        checkboxSelection
      />
    </div>
  );
};

export default Datatable;

Single.jsx:

//...

const Single = ({ inputs, title }) => {
  const [data, setData] = useState({
    code: "",
    article: "",
    price: 0,
    vat: 0,
    status: 0,
    company_id: 0,
  });

  const normalize = (v) => ({
    code: v.code,
    article: v.article,
    price: Number(v.price),
    vat: Number(v.vat),
    status: Number(v.status),
    company_id: Number(v.company_id),
  });

  function handle(e) {
    const newdata = { ...data };
    newdata[e.target.id] = e.target.value;
    setData(newdata);
    console.log(newdata);
  }

  const handleClick = async (e) => {
    e.preventDefault();
    const body = normalize(data);

    await fetch("https://api.factarni.tn/article/create", {
      method: "PUT",
      body: JSON.stringify(body),
      headers: {
        "Content-Type": "application/json",
        Authorization:
          "Bearer eyJhbGciOiJ...w2QWltkyA",
      },
    });
  };

  return (
    <div className="New">
      <Sidebar />
      <div className="newContainer">
        <Navbar />
        <div className="top">
          <h1>{title}</h1>
        </div>
        <div className="bottom">
          <div className="right">
            <form>
              <div className="formInput"></div>
              {inputs.map((input) => (
                <div className="formInput" key={input.id}>
                  <label>{input.label} </label>
                  <input
                    type={input.type}
                    placeholder={input.placeholder}
                    onChange={(e) => handle(e)}
                    id={input.label}
                    name={input.label}
                    value={input.label}
                  />
                </div>
              ))}
              <button onClick={handleClick}>Update</button>
            </form>
          </div>
        </div>
      </div>
    </div>
  );
};

export default Single;

Ava
  • 512
  • 2
  • 26

2 Answers2

2

In the Database.jsx:

// ... code
<Link to={{ pathname: "/users/test", state: { id: params.row.id }}} style={{ textDecoration: "none" }}>
    <div className="viewButton">Modifier</div>
</Link>
// ... code

In the Single.jsx:

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

// ... later in render function
const { state } = useLocation() // state.id should have your id
deaponn
  • 837
  • 2
  • 12
1

Although @deaponn's answer is good, you can also use the useNavigate hook and pass the id, name or any data in the state like below, using programmatic approach rather than Link component exported from react-router library

import { useNavigate } from "react-router-dom";
    
const navigate = useNavigate();
navigate('/(url on which you want to navigate)', { state: { id:1,name:encryptedId} });

On the navigated component, if you want to retrieve the passed id or name, you can use the useLocation hook as below:

import { useLocation } from "react-router-dom";
    
const location = useLocation();
var ttid = location.state.id;
deaponn
  • 837
  • 2
  • 12
Anshul
  • 51
  • 1
  • 10
  • The usage of `useNavigate` hook presented in your answer is misleading: _navigate('/(component on which you want to navigate)'_ - instead of "(component on which you want to navigate)" there should be "(url you want to navigate)". Also my answer isn't an alternative, as OP himself is using `Link` in the app, maybe he doesn't want to change the location programatically. – deaponn Sep 19 '22 at 12:05