【问题标题】:Convert React class component to react hooks将 React 类组件转换为反应钩子
【发布时间】:2020-11-08 15:22:15
【问题描述】:

嗨,我是新手,我正在制作一个模因生成器。我试图将它从一个类转换为反应钩子,不知道为什么它不起作用。这是我目前所拥有的,当我尝试生成新图像时出现错误。

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: undefined is not an object (evalating 'allMemeImgs[randNum].url')

【问题讨论】:

  • setallMemeImages({allMemeImgs: memes}) 应该是setallMemeImages(memes)
  • 应该是setallMemeImages(memes);

标签: reactjs react-native


【解决方案1】:
const [allMemeImgs, setallMemeImages] = useState([]);

allMemeImgs 是本地状态的数组。但是在这里setallMemeImages({allMemeImgs: memes}) 你将它设置为一个对象。

改成setallMemeImages((prev) =&gt; [...prev, memes])

【讨论】:

    【解决方案2】:

    您希望为 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]);
    

    【讨论】:

      【解决方案3】:

      注意您也可以使用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/react@16.7.0-alpha.0/umd/react.development.js"></script>
      <script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
      
      <div id="app"></div>

      【讨论】:

        猜你喜欢
        • 2020-09-17
        • 1970-01-01
        • 2019-09-01
        • 1970-01-01
        • 2020-11-30
        • 1970-01-01
        • 1970-01-01
        • 2021-02-05
        • 2023-03-25
        相关资源
        最近更新 更多