我正在通过以下代码进行操作:
index.js
import React, {useRef, useState, useEffect} from "react";
import ReactDOM from "react-dom";
import AddAPhotoTwoTone from '@material-ui/icons/AddAPhotoTwoTone'
import backImg from "./background.png";
const Canvas = (props) => {
const canvas = useRef(null);
const image = useRef(null);
const xLoc = useState(props.backImg.width/2)
const yLocTop = useState(props.backImg.height/2)
const yLocBottom = useState(props.backImg.height/2)
useEffect(() => {
const ctx = canvas.current.getContext("2d");
image.current.onload = () => {
ctx.drawImage(image.current, 0, 0);
ctx.font = "20px Courier";
ctx.textAlign = "center";
console.log(xLoc)
ctx.fillText(props.textTop, xLoc, yLocTop);
ctx.textAlign = "center";
ctx.fillText(props.textBottom, xLoc, yLocBottom);
};
});
useEffect(() => {
const ctx = canvas.current.getContext("2d");
ctx.drawImage(image.current, 0, 0);
// const xLoc = canvas.current.width/2
// const yLocTop = canvas.current.height*.95
// const yLocBottom = canvas.current.height*0.05
ctx.font = "20px Courier";
ctx.textAlign = "center";
ctx.fillText(props.textTop, xLoc, yLocTop);
ctx.textAlign = "center";
ctx.fillText(props.textBottom, xLoc, yLocBottom);
});
return (
<div>
<canvas ref={canvas} width={props.backImg.width} height={props.backImg.height} />
<img ref={image} src={props.backImg} hidden/>
</div>
);
};
function App() {
return (
<div className="App">
<Canvas textTop="TEST 123" textBottom="TEST 456" backImg={backImg} />
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
为什么console.log(xLoc)
在最初的useEffect
中打印NaN
?
useEffect(() => {
const ctx = canvas.current.getContext("2d");
image.current.onload = () => {
ctx.drawImage(image.current, 0, 0);
ctx.font = "20px Courier";
ctx.textAlign = "center";
console.log(xLoc)
ctx.fillText(props.textTop, xLoc, yLocTop);
ctx.textAlign = "center";
ctx.fillText(props.textBottom, xLoc, yLocBottom);
};
});
沙盒代码为here
编辑:
即使已正确配置useState
,它也会在控制台上返回NaN。
答案 0 :(得分:5)
useState()
返回一个数组。第一个元素是状态值,第二个元素是状态更新功能。您需要像这样破坏输出。
需要成为
const [xLoc, setxLoc] = useState(props.backImg.width/2)
const [yLocTop, setyLocTop] = useState(props.backImg.height/2)
const [yLocBottom, setyLocBottom] = useState(props.backImg.height/2)
因此,您传递给useState()
的任何内容都将是初始值。
另外。问题是props.backImg
只是一个字符串。它没有像.width
和.height
这样的对象属性。要实际访问这些值,您需要首先将该图像用作src
标记内的img
。
然后,img
标记可以访问onLoad
事件侦听器。使用事件处理程序,我们可以访问提到的对象属性。
从某种意义上说,我们首先需要在屏幕上渲染图像,但是直到我们渲染Canvas组件时,这种情况才会发生,因此不需要从App中传递这些道具。有关更多详细信息,请参见沙箱。