我想使用 react hook 'useState' 来保存从 API 获取的信息并显示在 scrren 上。但是,我不能在 class 中使用,所以我该怎么办?

I want to use react hook 'useState' to save the information fetched from API and show on the scrren. But, I can't use in class so what can I do?

因此,在某些情况下,我会在单击搜索按钮时获取一些搜索结果。完美点击搜索按钮后,结果显示在 console.log() 中。 SearchComponent.js 在下方。

import React, { Component, useState } from 'react'
import { API_KEY, API_URL } from '../config/keys';
import { Link } from 'react-router-dom';

class SearchBox extends Component {

constructor(props) {
    super(props);

    this.state = {
      searchQuery: ""
    }

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.onChangeValue = this.onChangeValue.bind(this);
  }

handleChange = (e) => {
    e.preventDefault();
    const { name, value } = e.target;
    this.setState({ [name]: value });
}

handleSubmit = (e) => {

    e.preventDefault();
    var data = this.state.searchQuery;
    const url = `${API_URL}search/${this.state.selectedOption}?api_key=${API_KEY}&language=en-US&query=${encodeURI(data)}&page=1&include_adult=false`;

    fetch(url)
    .then(response => response.json())
    .then(response => {
        console.log(response);
        const result = response.results; 
    })
}

onChangeValue(event) {
    this.setState({
        selectedOption: event.target.value
      });
}

render() {
return (
    <>
    <div className="mt-3">
    {/* Breadcrumb */}
        <div style={{ width: '95%', margin: '1rem auto' }}>
            <nav aria-label="breadcrumb">
                <ol className="breadcrumb">
                    <li className="breadcrumb-item"><Link to='/'>Home</Link></li>
                    <li className="breadcrumb-item active" aria-current="page">Search</li>
                </ol>
            </nav>
        </div>

        <div className="row">
            <div className="col-6 offset-3">
                <form className="form-group">
                    <div className="input-group">
                        <input 
                        className="form-control"
                        type="text"
                        placeholder= 'Search...'
                        onChange={this.handleChange}
                        name= 'searchQuery'
                        value={this.state.searchQuery} /> 
                        <button onClick={this.handleSubmit} type="submit" className="btn btn-primary input-group-addon" ><span className="fa fa-search fa-lg"></span></button>
                    </div>
                    {/* radio buttons */}
                    <div className="mt-2">
                        <div class="form-check">
                            <input 
                            class="form-check-input" 
                            type="radio" 
                            name="movie" 
                            value="movie"
                            checked={this.state.selectedOption === "movie"}
                            onChange={this.onChangeValue}
                            />
                            <span class="form-check-label font-weight-bold">
                                Movies
                            </span>
                        </div>
                        <div class="form-check">
                            <input 
                            class="form-check-input" 
                            type="radio" 
                            value="tv" 
                            name="tvshow" 
                            checked={this.state.selectedOption === "tv"}
                            onChange={this.onChangeValue}
                            />
                            <span class="form-check-label font-weight-bold">
                                TV Shows
                            </span>
                        </div>
                    </div>
                </form>
            </div>
        </div>
    </div>

    {/* search results */}
    <div style={{ width: '95%', margin: '1rem auto' }}>
        <div className="text-center">
            <div className="font-weight-lighter h2"> Search Results </div>

        </div>
    </div>
    </>
)
}
}

export default SearchBox;

结果数组在handleSubmit()result变量中。我如何使用 useState 来存储我的 result var 然后在 scrren.

上显示它

如果您不明白我在谈论如何使用这个挂钩,我已经附上了一个做类似事情的文件。 landingComponent.js

import React, { useEffect, useState } from 'react';
import {API_URL, API_KEY, IMAGE_URL} from '../../config/keys';
import { Row } from 'reactstrap';
import MainImage from './MainImage';
import GridCard from './GridCard';
import { Link } from 'react-router-dom';


function LandingPage() {

const [Movies, setMovies] = useState([]);
const [CurrentPage, setCurrentPage] = useState(0);

useEffect( () => {
    const endpoint = `${API_URL}movie/popular?api_key=${API_KEY}&language=en-US&page=1`;
    fetchMovies(endpoint);
}, []);

const fetchMovies = (path) => {
    fetch(path)
    .then(response => response.json())
    .then(response => {
        console.log(response);
        setMovies([...Movies, ...response.results]);
        setCurrentPage(response.page);
    })
}

const handleClick = () => {
    const endpoint = `${API_URL}movie/popular?api_key=${API_KEY}&language=en-US&page=${CurrentPage + 1}`
    fetchMovies(endpoint);
}

return (
    <div style={{ width: '100%', margin: 0 }}  >

        

        <div style={{ width: '95%', margin: '1rem auto' }}>
            {/* Breadcrumbs */}
            <nav aria-label="breadcrumb">
                <ol className="breadcrumb">
                    <li className="breadcrumb-item"><Link to='/'>Home</Link></li>
                    <li className="breadcrumb-item active" aria-current="page">Movies</li>
                </ol>
            </nav>
            <div className="font-weight-bold h2"> Latest Movies </div>
            <hr style={{borderColor:'black'}}/>

            <Row>
                    {Movies && Movies.map((movie, index) => (
                        <React.Fragment key={index}>
                            <GridCard 
                                image={movie.poster_path && `${IMAGE_URL}w500${movie.poster_path}`}
                                movieId={movie.id} movieTitle={movie.title} name={movie.original_title}
                            />
                        </React.Fragment>
                    ))}
            </Row>

            <br />
            <div className="text-center">
                <button className="btn btn-primary" onClick={handleClick}> Load More </button>
            </div>

        </div>

    </div>
)
}

export default LandingPage

我想在 SearchComponent.js 中使用相同的方法。我尝试了很多东西,但 none 奏效了。感谢帮助。

React 有两种使用组件的方式:

Class 个组件

这样声明:class ComponentName extends Component {

然后您的状态使用以下方式进行管理:this.setState()

函数组件

与第二个示例一样声明为函数

在那里你可以使用钩子和 useState()

因此,如果您不打算重写所有组件,则必须使用 this.setState()

当您获取数据时,您需要再次将其存储在状态中,从而在状态中创建 results:[] 属性。

handleSubmit = (e) => { 
    e.preventDefault();
    var data = this.state.searchQuery;
    const url = `${API_URL}search/${this.state.selectedOption}?api_key=${API_KEY}&language=en-US&query=${encodeURI(data)}&page=1&include_adult=false`;

    fetch(url)
    .then(response => response.json())
    .then(response => {
        console.log(response);
        const result = response.results; 
        this.setState({results:result}); //Here you store the state.
    });
}

现在您必须在 results JSX block 中显示它。

{/* search results */}
<div style={{ width: '95%', margin: '1rem auto' }}>
  <div className="text-center">
    <div className="font-weight-lighter h2"> Search Results </div>
    <div className="results">
      <ul>
        {this.state.results.length && this.state.results.map(item => { return (
        <li> {item} </li>
        ) })}
      </ul>

    </div>
  </div>
</div>