在React中,导航到另一个组件时状态值会更改

问题描述 投票:0回答:1

我刚开始反应,我正在做一个简单的项目来学习反应。在这种情况下,在组件之间导航或在浏览器中按返回按钮时,状态值将更改为null。 (即初始化之前的值)。我的问题是在组件之间导航或在浏览器中按返回按钮时如何保留状态值。这是我的示例代码:附言忽略CSS。

  1. App.js

class App extends Component {
    state = {movies:[]};

    //This method fetches the movie details
    searchMovie = (movieQuery) => {
        fetch(`http://www.omdbapi.com/?apikey=111111&s=${movieQuery}`) //Removed the apikey
        .then((response) => response.json())
        .then((json) => {
            this.setState({movies:json.Search});
        })
        .catch((err)=> {console.log(err.message);})
    }

    render() {
        return (
            <div>
                <Search searchMovie = {this.searchMovie}/> 
                <div className="container-fluid">
                    <div className="row" id='movies'>
                        {
                            this.state.movies.map((movie) => {
                                const {imdbID,Title,Poster} = movie;
                                return(
                                    <div key={imdbID} className='card card-body col-md-3 col-sm-4 m-3' id='movie-card' style={{cursor:'pointer'}}>
                                        <Link to = {{
                                            pathname:'/movie',
                                            state:{imdbID:imdbID}
                                        }}>
                                        <img src={Poster} className='img-fluid mx-auto poster-img' onError={(e)=>{e.target.onerror = null; e.target.src='https://cm3inc.com/wp-content/uploads/2016/08/npa2.jpg'}}/>
                                        <p className='movie-title'>{Title}</p>
                                        </Link>
                                    </div>
                                )
                            })
                        } 
                    </div>
                </div>
            </div>
        )
    }
}

export default App;   
  1. Search.js
import React, { Component } from "react";


class Search extends Component {
    state = { movieQuery: '' }; //this value changes when navigating between components

    searchQuery = (event) => {
        this.setState({ movieQuery: event.target.value });
    }

    handleKeyPress = (event) => {
        if (event.key === "Enter") {
            this.props.searchMovie(this.state.movieQuery);
        }
    }


    render() {
        return (
            <div>
                <div className="jumbotron">
                    <h1 style={{textShadow: '2px 2px 4px #000000'}}>Movie Master</h1>
                    <p className="lead" style={{marginBottom:'10px'}}>This is a handy site to search details for a movie or series based on IMDB Data.</p>
                    <input className="search-input mr-2"
                        placeholder="Search Movie/Series Here..."
                        onChange={this.searchQuery}
                        onKeyPress={this.handleKeyPress} 
                    />
                    <button className="btn btn-primary my-2" onClick={this.props.searchMovie}>Search</button>
                </div>
            </div>
        )
    }
}

export default Search;

3。Movie.js

class Movie extends Component {
    state = { movie: [] };
    componentDidMount() {
        const { imdbID } = this.props.location.state;
        fetch(`http://www.omdbapi.com/?apikey=5f0c4ce7&i=${imdbID}`)
            .then((response) => { return response.json(); })
            .then((json) => {
                this.setState({ movie: json });
                console.log(this.state.movie);
            })
    }

    render() {
        if (!this.state.movie.Ratings) return null;
        return (
            <div>
                <div className='container'>
                    <div className='card my-5'>
                        <div className='row'>
                            <div className='col-md-4'>
                                <img src={this.state.movie.Poster} className='img-fluid movie-image' style={{ width: '100%', height: '100%' }} onError={(e) => { e.target.onerror = null; e.target.src = 'https://cm3inc.com/wp-content/uploads/2016/08/npa2.jpg' }} />
                            </div>
                            <div className='col-md-8'>
                                <h3 className='movie-heading'>{this.state.movie.Title}</h3>
                                <ul className="list-group movie-details">
                                    <li className="list-group-item">
                                        <strong>Genre : &nbsp;</strong> {this.state.movie.Genre}
                                    </li>
                                    <li className="list-group-item">
                                        <strong>Released : &nbsp;</strong> {this.state.movie.Released}
                                    </li>
                                    <li className="list-group-item">
                                        <strong>Director : &nbsp;</strong> {this.state.movie.Director}
                                    </li>
                                    <li className="list-group-item">
                                        <strong>Writer : &nbsp;</strong> {this.state.movie.Writer}
                                    </li>
                                    <li className="list-group-item">
                                        <strong>Actors : &nbsp;</strong> {this.state.movie.Actors}
                                    </li>
                                    <li className="list-group-item">
                                        <strong>Rated : &nbsp;</strong> {this.state.movie.Rated}
                                    </li>
                                    <li className="list-group-item">
                                        <strong>Runtime : &nbsp;</strong> {this.state.movie.Runtime}
                                    </li>
                                    <li className="list-group-item">
                                        <strong>Production : &nbsp;</strong> {this.state.movie.Production}
                                    </li>
                                    <li className="list-group-item">
                                        <strong>Awards : &nbsp;</strong> {this.state.movie.Awards}
                                    </li>
                                </ul>
                            </div>
                        </div>
                        <div className='row' style={{ marginTop: '0px' }}>
                            <div className='col-12'>
                                <div className="card plot-card">
                                    <div className="card-header">Plot</div>
                                    <div className="card-body">
                                        <p className="card-text">{this.state.movie.Plot}</p>
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div className='row' style={{ marginTop: '0px' }}>
                            <div className='col-md-4'>
                                <ul className='list-group'>
                                    <li className="list-group-item">
                                        <strong>IMDB Rating : &nbsp;</strong> {this.state.movie.imdbRating} /10
                                            </li>
                                    <li className="list-group-item">
                                        <strong>IMDB Votes : &nbsp;</strong> {this.state.movie.imdbVotes}
                                    </li>
                                    <li className="list-group-item">
                                        <strong>Box Office : &nbsp;</strong> {this.state.movie.BoxOffice}
                                    </li>
                                </ul>
                            </div>
                            <div className='col-md-8'>
                                <div className="card-deck text-center">
                                    {
                                        this.state.movie.Ratings.map((rating) => {
                                            return (
                                                <div className="card rating-card" key={this.state.movie.imdbID}>
                                                    <div className="card-header">{rating.Source}</div>
                                                    <div className="card-body">
                                                        <p className="card-text">{rating.Value}</p>
                                                    </div>
                                                </div>
                                            )
                                        })
                                    }
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        )
    }
}

export default Movie;
reactjs
1个回答
0
投票

反应状态是短暂的。并且,当卸载某个组件时,它将重置其状态,以便说出该组件,以便下次安装时,它将再次使用初始状态。如果您需要整个应用程序的状态管理,请考虑使用redux。

如果在后退按钮或页面刷新后需要更大的持久性,请考虑使用本地或会话存储

© www.soinside.com 2019 - 2024. All rights reserved.