简体   繁体   English

在新路由中管理单击项目的道具 - React 路由器 v6

[英]Managing clicked item's props in a new route - React router v6

I have a map of an objects.我有一个对象的 map。 Each object is an item in a list.每个 object 都是列表中的一个项目。 When I click on a concrete item it moves me to a specific route with that item's id .当我单击一个具体项目时,它会将我移动到具有该项目 id的特定路线。 How to properly manage that concrete item's props inside new route?如何在新路线中正确管理该具体项目的道具?

Is this the way to go or there is better way?这是通往 go 的方法还是有更好的方法?

export const Router = (): ReactElement => {
  const [itemDetails, setItemDetails] = useState<Item>();
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Root />}>
          <Route
            index
            element={<ItemList setItemDetails={setItemDetails} />}
          />
          <Route
            path="/item/:itemId"
            element={<ItemDetails itemDetails={itemDetails} />}
          />
        </Route>
      </Routes>
    </BrowserRouter>
  );
};

So basically what I'm doing here is I'm passing state setter function to a list where my mapped items are stored so when I click on a concrete one I save its props to that function.所以基本上我在这里做的是我将 state 设置器 function 传递到存储我的映射项目的列表,所以当我点击一个具体的项目时,我将它的道具保存到 ZC1C425268E68385D1AB5074C。

Then I just pass updated state to a new route where details of a concrete item should be displayed.然后我只是将更新后的 state 传递到应显示具体项目详细信息的新路线。

If you are asking if there's a better way than pushing some value from ItemList up to the parent state to be passed down to ItemDetails , then sure, a more React/ react-router-dom way would be to hoist the items array from the ItemList component up to this parent component and pass the data down to children routes as props or via a context.如果您问是否有比将某些值从ItemList推送到父 state 以传递给ItemDetails的方法,那么可以肯定,更 React/ react-router-dom方法是从ItemList提升 items 数组组件到这个父组件,并将数据作为道具或通过上下文传递给子路由。

Example using props使用道具的示例

export const Router = (): ReactElement => {
  const [items, setItems] = useState<Array<Item>>([]);

  ... logic to populate items state ...

  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Root />}>
          <Route index element={<ItemList items={items} />} />
          <Route path="/item/:itemId" element={<ItemDetails items={items} />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );
};

ItemDetails项目详情

const ItemDetails = ({ items }) => {
  const { itemId } = useParams();
  const item = items.find(item => String(item.id) === itemId);

  if (!item) {
    return <div>No matching item found.</div>;
  }
  return (
    ... render item out to JSX
  );
};

Example using Outlet context使用 Outlet 上下文的示例

export const Router = (): ReactElement => {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Root />}>
          <Route index element={<ItemList />} />
          <Route path="/item/:itemId" element={<ItemDetails />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );
};

Root

const Root = () => {
  const [items, setItems] = useState<Array<Item>>([]);

  ... logic to populate items state ...

  return (
    ...
    <Outlet context={{ items }} />
    ...
  );
};

ItemList物品清单

const ItemList = () => {
  const { items } = useOutletContext();

  return (
    ... map items to JSX
  );
};

ItemDetails项目详情

const ItemDetails = () => {
  const { items } = useOutletContext();
  const { itemId } = useParams();
  const item = items.find(item => String(item.id) === itemId);

  if (!item) {
    return <div>No matching item found.</div>;
  }
  return (
    ... render item out to JSX
  );
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM