【发布时间】:2021-02-03 21:40:52
【问题描述】:
我是 useContext 钩子的新手,并试图找出我做错了什么......没有顶级导入,这是我的代码的样子:
所以我的项目的根是这样的:
export default function App() {
return (
<div className="App">
<AppProvider>
<Header/>
<Toolbar/>
<Canvas/>
<Imports/>
<Footer/>
</AppProvider>
</div>
);
}
然后我有一个名为 AppProvider 的单独文件,其中包含:
const CanvasItems = createContext();
const UpdateCanvasItems = createContext();
export function useCanvasItems() {
return useContext(CanvasItems)
}
export function useChangeItems() {
return useContext(UpdateCanvasItems)
}
export default function AppProvider({children}) {
const [state, setState] = useState({
imports: [],
images: [],
text: [],
circles: [],
rectangles: [],
draw: [],
})
// function pushes new items in to state object
function addCanvasItem(type, source) {
if (type === 'import') {
const tempState = [...state.imports];
tempState.push({id: Date.now(), image: source});
setState({...state, imports: tempState})
} else if (type === 'image') {
const tempState = [...state.images];
tempState.push({
id: Date.now(),
src: source.src,
x: window.innerWidth * Math.random(),
y: window.innerHeight * Math.random(),
})
setState({...state, images: tempState})
}
console.log("state after new item added:", state)
}
return (
<CanvasItems.Provider value={state}>
<UpdateCanvasItems.Provider value={addCanvasItem}>
{children}
</UpdateCanvasItems.Provider>
</CanvasItems.Provider>
)
}
我没有任何问题将state 对象和addCanvasItems 函数传递到子级的第一级(因此标题、工具栏、画布等),但我在这些组件中有子级,我可以'不访问值。
为了清楚起见 - 在Canvas 组件内部,我有一个Stage 组件,里面有一个Layer 组件,里面有一个Items 组件(我正在使用Konva 并且需要有所有这些嵌套)。
export default function Canvas() {
const { onDrop, onDragOver } = useDragDrop;
const state = useCanvasItems();
useEffect(() => {
console.log("state in canvas", state)
}, [state])
return (
<div id='canvas'>
<Stage
container='canvas'
onDrop={onDrop}
onDragOver={onDragOver}
>
<Layer>
<Items/>
</Layer>
</Stage>
</div>
)
}
我需要访问Items 组件中的state 对象,但我想避免道具钻孔。为了测试,我创建了一个useEffect 函数来在每次更改时打印状态。 Items 组件在第一次加载时打印undefined,而Canvas 组件打印整个对象。
export default function Items() {
const state = useCanvasItems();
useEffect(() => {
console.log("state in items", state)
}, [state])
return (
<>
{state && state.images.map(image => {
return <NewImage image={image} />
})}
</>
)
};
what prints to the console on load and after a file is imported (changing the state)
这个钩子我缺少什么以及如何实现它??
非常感谢您的帮助!! ??????????????????
【问题讨论】:
-
您能在此处的代码框中提供您的代码吗? codesandbox.io
标签: javascript reactjs react-props use-context