将 React 类组件转换为 React Hooks
2020-11-08
142
嗨,我是 React 的新手,我正在制作一个 meme 生成器。我试图将它从类转换为 React Hooks,不确定为什么它不起作用。这是我目前所拥有的,当我尝试生成新图像时,我收到错误。
import React, { useEffect, useState } from "react"
function MemeGenerator() {
const [newText, setNewText] = useState({
topText: "",
lastName: ""
})
const [randomImg, setrandomImg] = useState("http://i.imgflip.com/1bij.jpg")
const [allMemeImgs, setallMemeImages] = useState([])
useEffect(()=> {
fetch("https://api.imgflip.com/get_memes")
.then(response => response.json())
.then(response => {
const {memes} = response.data
setallMemeImages({allMemeImgs: memes})
})
},[])
function handleChange(event) {
const {name, value} = event.target
setNewText({
...newText,
[name]: value
})
}
// error is on this function I believe
function handleSubmit(event) {
event.preventDefault()
const randNum = Math.floor(Math.random() * allMemeImgs.length)
alert(randNum)
const randMemeImg = allMemeImgs[randNum].url
setrandomImg(randMemeImg)
}
return (
<div>
<form className="meme-form" onSubmit={handleSubmit}>
<input
type="text"
name="topText"
placeholder="Top Text"
value={newText.topText}
onChange={handleChange}
/>
<input
type="text"
name="bottomText"
placeholder="Bottom Text"
value={newText.bottomText}
onChange={handleChange}
/>
<button>Gen</button>
</form>
<div className="meme">
<img src={randomImg} alt="" />
<h2 className="top">{newText.topText}</h2>
<h2 className="bottom">{newText.bottomText}</h2>
</div>
</div>
)
}
我之前所拥有的有效的方法是:
import React, {Component} from "react"
class MemeGenerator extends Component {
constructor() {
super()
this.state = {
topText: "",
bottomText: "",
randomImg: "http://i.imgflip.com/1bij.jpg",
allMemeImgs: []
}
this.handleChange = this.handleChange.bind(this)
this.handleSubmit = this.handleSubmit.bind(this)
}
componentDidMount() {
fetch("https://api.imgflip.com/get_memes")
.then(response => response.json())
.then(response => {
const {memes} = response.data
this.setState({ allMemeImgs: memes })
})
}
handleChange(event) {
const {name, value} = event.target
this.setState({ [name]: value })
}
handleSubmit(event) {
event.preventDefault()
const randNum = Math.floor(Math.random() * this.state.allMemeImgs.length)
const randMemeImg = this.state.allMemeImgs[randNum].url
this.setState({ randomImg: randMemeImg })
}
render() {
return (
<div>
<form className="meme-form" onSubmit={this.handleSubmit}>
<input
type="text"
name="topText"
placeholder="Top Text"
value={this.state.topText}
onChange={this.handleChange}
/>
<input
type="text"
name="bottomText"
placeholder="Bottom Text"
value={this.state.bottomText}
onChange={this.handleChange}
/>
<button>Gen</button>
</form>
<div className="meme">
<img src={this.state.randomImg} alt="" />
<h2 className="top">{this.state.topText}</h2>
<h2 className="bottom">{this.state.bottomText}</h2>
</div>
</div>
)
}
错误内容: TypeError:未定义不是对象(评估“allMemeImgs[randNum].url”)
3个回答
const [allMemeImgs, setallMemeImages] = useState([]);
allMemeImgs
是本地状态中的一个数组。但在这里
setallMemeImages({allMemeImgs: memes})
您要将其设置为一个对象。
将其更改为
setallMemeImages((prev) => [...prev, memes])
Sarun UK
2020-11-08
您期望为 allMemeImgs 状态初始化一个数组
const [allMemeImgs, setallMemeImages] = useState([])
但已将其配置为此特定 useEffect 钩子中的一个对象
useEffect(()=> {
fetch("https://api.imgflip.com/get_memes")
.then(response => response.json())
.then(response => {
const {memes} = response.data
setallMemeImages({allMemeImgs: memes}) // culprit here
})
},[])
问题出在以下行:
setallMemeImages({allMemeImgs: memes})
建议将此行更改为:
setallMemeImages([...memes]);
Shashank Garg
2020-11-08
注意
您还可以使用
setallMemeImages([...memes]);
,但如果出现类型错误,请使用
setallMemeImages(memes);
,如果出现
randMemeImg
类型错误,请使用:
const randMemeImg = allMemeImgs[randNum];
setrandomImg(Object(randMemeImg).url);
function MemeGenerator() {
const [newText, setNewText] = React.useState({
topText: "",
bottomText: ""
})
const [randomImg, setrandomImg] = React.useState("http://i.imgflip.com/1bij.jpg")
const [allMemeImgs, setallMemeImages] = React.useState([])
React.useEffect(()=> {
fetch("https://api.imgflip.com/get_memes")
.then(response => response.json())
.then(response => {
const {memes} = response.data
setallMemeImages([...memes]);
})
},[])
function handleChange(event) {
const {name, value} = event.target
setNewText({
...newText,
[name]: value
})
}
function handleSubmit(event) {
event.preventDefault()
const randNum = Math.floor(Math.random() * allMemeImgs.length)
alert(randNum)
const randMemeImg = allMemeImgs[randNum].url
setrandomImg(randMemeImg)
}
return (
<div>
<form className="meme-form" onSubmit={handleSubmit}>
<input
type="text"
name="topText"
placeholder="Top Text"
value={newText.topText}
onChange={handleChange}
/>
<input
type="text"
name="bottomText"
placeholder="Bottom Text"
value={newText.bottomText}
onChange={handleChange}
/>
<button>Gen</button>
</form>
<div className="meme">
<img src={randomImg} alt="" />
<h2 className="top">{newText.topText}</h2>
<h2 className="bottom">{newText.bottomText}</h2>
</div>
</div>
)
}
ReactDOM.render(<MemeGenerator />, document.querySelector('#app'));
<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<div id="app"></div>
TheoNeUpKID
2020-11-08