使用 React useContext() 钩子传递对象 [英] Passing an object using React useContext() hook
问题描述
我有一个包含项目列表的视图.当我点击其中一个项目时,我想让面板显示所点击项目的所有详细信息.
这是我写的上下文文件
import React, { useContext, useState } from 'react';const ActivityPreviewContext = React.createContext();const ActivityPreviewUpdateContext = React.createContext();导出函数 useActivityPreview() {返回 useContext(ActivityPreviewContext);}导出函数 useActivityPreviewUpdate() {返回 useContext(ActivityPreviewUpdateContext);}导出函数 ActivityPreviewProvider({ children }) {const [activityPreview, setActivityPreview] = useState();功能活动预览更新(数据){设置活动预览(数据);}返回 (<ActivityPreviewContext.Provider value={activityPreview}><ActivityPreviewUpdateContext.Provider value={activityPreviewUpdate}>{孩子们}</ActivityPreviewUpdateContext.Provider></ActivityPreviewContext.Provider>)}
我正在像这样将其包装在我的路线中.到目前为止,这似乎工作正常
<ActivityPreviewProvider><SideMenu/><HomeView/></ActivityPreviewProvider></路线>
HomeView 是我显示长列表的地方.您会注意到 openPeekPanel() 函数正在调用 activityPreviewUpdate(e.currentTarget.id);
这有效,但尝试传递一个对象会给我一个错误.
这是我尝试过的:activityPreviewUpdate(e.currentTarget.id);
WORKS: 传递一个数字或字符串activityPreviewUpdate([1,2,3]);
WORKS: 传递一个数组activityPreviewUpdate({a:123, b:456});
BREAKS:传递一个数组
我想传递充满数据的整个对象,以便我可以将其添加到侧面板中.
您可以查看下面的代码.
import React, { useState } from 'react';从'react-router-dom'导入{useHistory};从'./ThumbnailGroup'导入缩略图组;从'./PanelPreview'导入PanelPreview;import { useActivityPreview, useActivityPreviewUpdate } from '../context/ActivityPreviewContext';const fakeData = [{编号:100,类型:视频",标题:我的标题",持续时间:2,问题:4,图片:https://picsum.photos/seed/1/200/150"},{编号:101,类型:视频",标题:我的标题",持续时间:2,问题:4,图片:https://picsum.photos/seed/2/200/150"}]const HomeView = (props) =>{const 历史 = useHistory();const [peekActive, setPeekActive] = useState(false);const [activeItem, setActiveItem] = useState(0);const activityPreview = useActivityPreview();const activityPreviewUpdate = useActivityPreviewUpdate();const closePeekPanel = () =>{let section_ele = document.querySelector(section");section_ele.classList.remove(activePanel");setPeekActive(false);}const openPeekPanel = (e) =>{活动预览更新(e.currentTarget.id);let section_ele = document.querySelector(section");section_ele.classList.add(activePanel");setPeekActive(true);}返回 (<div id="contentArea"><缩略图组名称=收藏夹"data={fakeData} title=最近收藏";onClick={openPeekPanel}/>
{peekActive &&<PanelPreview onClosePanel={closePeekPanel}/>}</节>);};导出默认的 HomeView;
目前我只在侧面板打印 ID.
import React, { useState } from 'react';import { NavLink, useHistory } from 'react-router-dom';从'./Card'导入卡片;从'./Icon'导入图标;导入 { useActivityPreview, ActivityPreviewProvider } from '../context/ActivityPreviewContext';const PanelPreview = (道具) =>{//钩子const 历史 = useHistory();const activityPreview = useActivityPreview();返回 (<Card id="panelPreview"><div className="panelHeader">{<p>{activityPreview}</p>}
</卡片>);};导出默认面板预览;
这是因为 React 不会在 HTML 中呈现 JSON,只会呈现字符串.e.currentTarget.id
呈现该字符串,并且 [1,2,3]
被加入并呈现为 123
.
如果您计划接受一个对象,您应该考虑在 p
元素中选择该属性.<p>{activityPreview.a}</p>
将显示123
没有错误.
尽管 JSON.Stringify({a:123, b:456})
可能是您要查找的内容,但要按原样显示整个对象,而不会中断.
I have a view with a list of items. When I click on one of the items I want to have the panel display all the details of the item that was clicked.
Here is the Context File I wrote
import React, { useContext, useState } from 'react';
const ActivityPreviewContext = React.createContext();
const ActivityPreviewUpdateContext = React.createContext();
export function useActivityPreview() {
return useContext(ActivityPreviewContext);
}
export function useActivityPreviewUpdate() {
return useContext(ActivityPreviewUpdateContext);
}
export function ActivityPreviewProvider({ children }) {
const [activityPreview, setActivityPreview] = useState();
function activityPreviewUpdate(data) {
setActivityPreview(data);
}
return (
<ActivityPreviewContext.Provider value={activityPreview}>
<ActivityPreviewUpdateContext.Provider value={activityPreviewUpdate}>
{children}
</ActivityPreviewUpdateContext.Provider>
</ActivityPreviewContext.Provider>
)
}
I am wrapping this in my routes like this. This seems to work fine so far
<Route path="/home">
<ActivityPreviewProvider>
<SideMenu />
<HomeView />
</ActivityPreviewProvider>
</Route>
HomeView is where I have long lists showing up. You will notice openPeekPanel() function is calling activityPreviewUpdate(e.currentTarget.id);
this works, but trying to pass an object gives me an error.
this what I've tried:
activityPreviewUpdate(e.currentTarget.id);
WORKS: passing a number or string
activityPreviewUpdate([1,2,3]);
WORKS: passing an array
activityPreviewUpdate({a:123, b:456});
BREAKS: passing an array
I would like to pass the entire object full of data so I could add it into the side panel.
You could view the code below.
import React, { useState } from 'react';
import { useHistory } from 'react-router-dom';
import ThumbnailGroup from './ThumbnailGroup';
import PanelPreview from './PanelPreview';
import { useActivityPreview, useActivityPreviewUpdate } from '../context/ActivityPreviewContext';
const fakeData = [
{
id: 100,
type: "video",
title: "My Title",
duration: 2,
questions: 4,
image: "https://picsum.photos/seed/1/200/150"
},
{
id: 101,
type: "video",
title: "My Title",
duration: 2,
questions: 4,
image: "https://picsum.photos/seed/2/200/150"
}
]
const HomeView = (props) => {
const history = useHistory();
const [peekActive, setPeekActive] = useState(false);
const [activeItem, setActiveItem] = useState(0);
const activityPreview = useActivityPreview();
const activityPreviewUpdate = useActivityPreviewUpdate();
const closePeekPanel = () => {
let section_ele = document.querySelector("section");
section_ele.classList.remove("activePanel");
setPeekActive(false);
}
const openPeekPanel = (e) => {
activityPreviewUpdate(e.currentTarget.id);
let section_ele = document.querySelector("section");
section_ele.classList.add("activePanel");
setPeekActive(true);
}
return (
<section id="homeView" className="panelView">
<div id="contentArea">
<ThumbnailGroup name="favorite" data={fakeData} title="Favorited recently" onClick={openPeekPanel} />
</div>
{peekActive && <PanelPreview onClosePanel={closePeekPanel} />}
</section>
);
};
export default HomeView;
At the moment I am only printing the ID in the side panel.
import React, { useState } from 'react';
import { NavLink, useHistory } from 'react-router-dom';
import Card from './Card';
import Icon from './Icon';
import { useActivityPreview, ActivityPreviewProvider } from '../context/ActivityPreviewContext';
const PanelPreview = (props) => {
//hooks
const history = useHistory();
const activityPreview = useActivityPreview();
return (
<Card id="panelPreview">
<div className="panelHeader">
{
<p>{activityPreview}</p>
}
</div>
</Card>
);
};
export default PanelPreview;
It's because React doesn't render JSON in HTML, only strings.
e.currentTarget.id
renders that string and [1,2,3]
is joined and rendered as 123
.
If you plan on accepting an object, you should consider selecting that property in the p
element. <p>{activityPreview.a}</p>
would display123
without errors.
Although JSON.Stringify({a:123, b:456})
might be what you're looking for, to display the entire object as-is, without breaking.
这篇关于使用 React useContext() 钩子传递对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!