reactjs - 反应上下文不更新组件
问题描述
我有两个组件需要能够读取和更改列表的上下文,但是当其中一个组件更新上下文时,另一个组件不会更新
除了上下文挂钩之外,还有更好的方法吗?如果没有,为什么它不更新,我该如何解决?
const WebsiteContext = createContext([]);
const WebsiteContextProvider = (props) => {
const [cards, setCards] = useState([]);
return (
<WebsiteContext.Provider value={[cards, setCards]}>
{props.children}
</WebsiteContext.Provider>
);
};
function LayersPanel(props) {
const [cards, setCards] = useContext(WebsiteContext);
return (
<Box className="layersPanel">
{cards.map((item) => (
<h1 className="layer">{item.name}</h1>
))}
</Box>
);
}
function ControlPanel(props) {
return (
<div className="ControlPanel">
<h1>hello world</h1>
<LayersPanel></LayersPanel>
</div>
);
}
function WebsiteBody(props) {
const [cards, setCards] = useContext(WebsiteContext);
const [{ droppedItem, didDrop, isOver, canDrop }, drop] = useDrop(() => ({
accept: "card",
drop: () => ({
name: "WebsiteBody",
}),
collect: (monitor) => ({
droppedItem: monitor.getItem(),
didDrop: monitor.didDrop(),
}),
}));
if (didDrop) {
const tempCardName =
droppedItem.card.name + " " + (item_id === 0 ? "" : item_id.toString());
const tempCard = droppedItem.card;
tempCard.name = tempCardName;
const temp_cards = cards;
temp_cards.push(tempCard);
setCards(temp_cards);
item_id += 1;
}
return (
<Box ref={drop} w="100vw" h="100vh" backgroundColor="yellow.400" display="flex">
{cards.map((item) => item.component.code)}
</Box>
);
}
let item_id = 0;
function WebsiteEditor(props) {
return (
<ChakraProvider>
<DndProvider backend={HTML5Backend}>
<WebsiteContextProvider>
<WebsiteBody></WebsiteBody>
<ControlPanel></ControlPanel>
</WebsiteContextProvider>
</DndProvider>
</ChakraProvider>
);
}
解决方案
- 您应该
useMemo
提供由提供商提供的任何非简单值;否则它将在每次渲染时重新计算。 - 您不是
setCards
用新对象调用,而是在cards
内部发生变异。使用 egsetCards([...cards, tempCard]);
确保您使用的是新对象。 - 你同样在内部改变了
card
被丢弃的东西。您可以制作一个浅拷贝const tempCard = {...droppedItem.card};
(并且您可以在其中组合名称更改{...droppedItem.card, name: tempCardName}
:) - 使用像你这样的全局变量
item_id
不是惯用的 React。考虑一个随机 ID,或者一个基于时间的 ID,或者如果您确实需要顺序 ID,它也应该是状态的一部分。 - 您可能希望为您的上下文状态考虑
useReducer
而不是对。useState
推荐阅读
- spring-boot - Spring Hateoas:使用 RESTTemplate 时,内容始终为空
- jquery - 使用 AJAX 从视图中控制器中的 Asp.Net MVC 调用方法
- algorithm - gzipped file is smaller than Shannon limit?
- mysql - 嵌套选择时 where 子句中的未知列
- beautifulsoup - 为什么一个元素在 Beautiful Soup 中看起来有四个孩子?
- javascript - react native redux中的useSelector中的状态未定义
- vue.js - Vue将数据传回多个级别
- c - 使用 c 的正弦系列
- pine-script - 为什么我在 Pine 中的代码显示奇怪的结果?
- reactjs - How to continue a video between Screens with StackNavigation in React Native?