我尝试制作一个简单的模因生成器,用户可以在其中添加文本并在单击时更改图像。两者都在工作,但我的清除按钮只清除输入字段,不会返回到第一个图像(array[o](。我的意思是,如果我conole.log;元素";上面写着";0";但它不会将图像更改为第一个图像。
到目前为止,我的App.js代码:
import React, { useEffect, useState } from "react";
import "./styles.css";
function useCounter(initialCount = 0) {
const [count, setCount] = React.useState(initialCount);
const increment = React.useCallback(() => setCount((c) => c + 1), []);
return { count, increment };
}
export default function App() {
let { count: element, increment } = useCounter(0);
const [memes, setMemes] = useState([]);
const [topText, setTopText] = useState("");
useEffect(() => {
async function asyncFunction() {
const initialResponse = await fetch("https://api.imgflip.com/get_memes");
const responseToJSON = await initialResponse.json();
setMemes(responseToJSON.data.memes);
}
asyncFunction();
}, []);
const clear = (e) => {
setTopText("");
element = 0;
console.log(element);
};
return (
<div className="App">
{memes[0] ? (
<div
style={{
height: "300px",
backgroundImage: `url(${memes[element].url})`
}}
>
<p>{topText}</p>
<input
value={topText}
onChange={(e) => setTopText(e.target.value)}
type="text"
/>
<button onClick={clear} type="reset">Clear</button>
<button onClick={increment}>Change Image</button>
</div>
) : (
"loading"
)}
</div>
);
}
怎么了?
您正试图改变状态。您永远不应该直接将新值分配给有状态变量element = 0
。您应该使用useState
(setCount
(中提供的更新程序函数。
一个解决方案是为您的自定义挂钩添加一个重置功能并使用它:
function useCounter(initialCount = 0) {
const [count, setCount] = React.useState(initialCount);
const increment = React.useCallback(() => setCount((c) => c + 1), []);
const reset = () => setCount(initialCount);
return { count, increment, reset };
}
在您的组件中:
const { count: element, increment, reset: resetCount } = useCounter(0);
const clear = (e) => {
setTopText("");
resetCount();
};
注意,我还将自定义挂钩更改为使用const
而不是let
。建议这样做是为了鼓励状态的不可变使用,并在违反该规则时给出有用的错误。