P粉5010077682023-09-03 00:25:16
useStateRef
似乎是一種反模式。您決定新狀態是什麼,所以如果您需要另一個對它的引用,您總是可以自己建立一個。我建議盡量減少畫布上的屬性,以防止不必要的重新渲染。
function App({ width, height }) { const canvas = React.useRef() const [color, setColor] = React.useState("white") // when color changes.. React.useEffect(() => { if (canvas.current) { const context = canvas.current.getContext('2d'); context.fillStyle = color context.fillRect(0, 0, width, height) } }, [color, width, height]) return <div> <canvas ref={canvas} width={width} height={height} /> <button onClick={_ => setColor("blue")} children="blue" /> <button onClick={_ => setColor("green")} children="green" /> <button onClick={_ => setColor("red")} children="red" /> </div> } ReactDOM.createRoot(document.querySelector("#app")).render(<App width={200} height={150} />)
canvas { display: block; border: 1px solid black; }
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> <div id="app"></div>
或也許沒有理由將顏色儲存為狀態。您可以自行建立setColor
函數並將其附加為事件監聽器 -
function App({ width, height }) { const canvas = React.useRef() const setColor = color => event => { if (canvas.current) { const context = canvas.current.getContext('2d'); context.fillStyle = color context.fillRect(0, 0, width, height) } } return <div> <canvas ref={canvas} width={width} height={height} /> <button onClick={setColor("blue")} children="blue" /> <button onClick={setColor("green")} children="green" /> <button onClick={setColor("red")} children="red" /> </div> } ReactDOM.createRoot(document.querySelector("#app")).render(<App width={200} height={150} />)
canvas { display: block; border: 1px solid black; }
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script> <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script> <div id="app"></div>
我還建議您查看SVG。我發現SVG的API與React模式更契合,比Canvas API更好。每個的功能不同,但如果SVG適用於您的需求,那麼值得考慮。