我在玩React Hooks并且遇到了一个问题。当我尝试使用由事件侦听器处理的按钮进行控制台记录时,它显示错误的状态。
代码沙盒: https ://codesandbox.io/s/lrxw1wr97m
- 单击“添加卡”按钮 2 次
- 在第一张卡片中,单击Button1并在控制台中看到有 2 张卡片处于状态(正确的行为)
- 在第一张卡片中,单击Button2(由事件侦听器处理)并在控制台中看到只有 1 张卡片处于状态(错误行为)
为什么它显示错误的状态?
在第一张卡片中,Button2
应该2
在控制台中显示卡片。有任何想法吗?
const { useState, useContext, useRef, useEffect } = React;
const CardsContext = React.createContext();
const CardsProvider = props => {
const [cards, setCards] = useState([]);
const addCard = () => {
const id = cards.length;
setCards([...cards, { id: id, json: {} }]);
};
const handleCardClick = id => console.log(cards);
const handleButtonClick = id => console.log(cards);
return (
<CardsContext.Provider
value={{ cards, addCard, handleCardClick, handleButtonClick }}
>
{props.children}
</CardsContext.Provider>
);
};
function App() {
const { cards, addCard, handleCardClick, handleButtonClick } = useContext(
CardsContext
);
return (
<div className="App">
<button onClick={addCard}>Add card</button>
{cards.map((card, index) => (
<Card
key={card.id}
id={card.id}
handleCardClick={() => handleCardClick(card.id)}
handleButtonClick={() => handleButtonClick(card.id)}
/>
))}
</div>
);
}
function Card(props) {
const ref = useRef();
useEffect(() => {
ref.current.addEventListener("click", props.handleCardClick);
return () => {
ref.current.removeEventListener("click", props.handleCardClick);
};
}, []);
return (
<div className="card">
Card {props.id}
<div>
<button onClick={props.handleButtonClick}>Button1</button>
<button ref={node => (ref.current = node)}>Button2</button>
</div>
</div>
);
}
ReactDOM.render(
<CardsProvider>
<App />
</CardsProvider>,
document.getElementById("root")
);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id='root'></div>
我正在使用 React 16.7.0-alpha.0 和 Chrome 70.0.3538.110
顺便说一句,如果我使用类重写 CardsProvider,问题就消失了。CodeSandbox 使用类:https ://codesandbox.io/s/w2nn3mq9vl