Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React.js-使用分页交互进行搜索_Javascript_Reactjs - Fatal编程技术网

Javascript React.js-使用分页交互进行搜索

Javascript React.js-使用分页交互进行搜索,javascript,reactjs,Javascript,Reactjs,我正在使用React.js构建我的第一个应用程序。 应用程序使用外部电影API()来搜索和列出电影。 请求获取参数“query”和可选的“page”。响应已包含结果总数和现有页面总数。 示例响应如下所示: { "page": 1, "results": [ { "adult": false, "backdrop_path": "/8uO0gUM8aNqYLs1OsTBQiXu0fEv.jpg", "genre_ids": [18], "id": 550, "orig

我正在使用React.js构建我的第一个应用程序。 应用程序使用外部电影API()来搜索和列出电影。 请求获取参数“query”和可选的“page”。响应已包含结果总数和现有页面总数。 示例响应如下所示:

 {
 "page": 1,
 "results": [
  {
  "adult": false,
  "backdrop_path": "/8uO0gUM8aNqYLs1OsTBQiXu0fEv.jpg",
  "genre_ids": [18],
  "id": 550,
  "original_language": "en",
  "original_title": "Fight Club",
  "overview": "A ticking-time-bomb insomniac and a slippery soap salesman channel primal male aggression into a shocking new form of therapy. Their concept catches on, with underground \"fight clubs\" forming in every town, until an eccentric gets in the way and ignites an out-of-control spiral toward oblivion.",
  "release_date": "1999-10-14",
  "poster_path": "/811DjJTon9gD6hZ8nCjSitaIXFQ.jpg",
  "popularity": 4.39844,
  "title": "Fight Club",
  "video": false,
  "vote_average": 7.8,
  "vote_count": 3527
},
{
  "adult": false,
  "backdrop_path": "/qrZssI8koUdRxkYnrOKMRY3m5Fq.jpg",
  "genre_ids": [
    27
  ],
  "id": 289732,
  "original_language": "zh",
  "original_title": "Zombie Fight Club",
  "overview": "It's the end of the century at a corner of the city in a building riddled with crime - Everyone in the building has turned into zombies. After Jenny's boyfriend is killed in a zombie attack, she faces the challenge of surviving in the face of adversity. In order to stay alive, she struggles with Andy to flee danger.",
  "release_date": "2014-10-23",
  "poster_path": "/7k9db7pJyTaVbz3G4eshGltivR1.jpg",
  "popularity": 1.621746,
  "title": "Zombie Fight Club",
  "video": false,
  "vote_average": 3.5,
  "vote_count": 2
}
],
  "total_pages": 1,
  "total_results": 2
}
我选择的结构如下:

MovieSearchPage
- SearchForm
- SearchResults
--MovieBox
--Pagination
---Page
这是我的解决方案,几乎可以正常工作:

        var SearchResults = React.createClass({
            handlePageChange: function(pageNum) {
                this.props.onPageChange(pageNum);
            },
            render: function() {
                var movies = [];

                this.props.data.results.forEach(function(movie) {
                    movies.push(<MovieBox movie={movie} key={movie.id}/>);
                });

                return (
                   <div>
                   <h3>Search results ({this.props.data.total_results} found)</h3>
                   <Pagination onPageClick={this.handlePageChange} currentPage={this.props.data.page} totalPages={this.props.data.total_pages} totalResults={this.props.data.total_results}/>
                   <div>{movies}</div>
                   </div>
                );
            }
        });

        var SearchBar = React.createClass({
            getInitialState: function() {
                return {query: ''};
            },
            handleQueryChange: function(e) {
                this.setState({query: e.target.value});
            },
            handleSubmit: function(e) {
                e.preventDefault();
                var query = this.state.query.trim();
                if (!query || query.length < 3) {
                    return;
                }
                this.props.onSearch(query);
            },
            render: function() {
                return (
                   <form className="searchForm" onSubmit={this.handleSubmit}>
                    <input 
                        type="text" 
                        name="query" 
                        placeholder="Search for a movie..."
                        value={this.state.query}
                        onChange={this.handleQueryChange}
                    />
                    <input type="submit" value="Search Movie"/>
                   </form>
                );
            }
        });

        var MovieBox = React.createClass({
            render: function() {
                var m = this.props.movie;
                return (
                   <div className="movieBox">
                        <div>{m.original_title} ({m.release_date})</div>
                   </div>
                );
            }
        });

        var Pagination = React.createClass({
            render: function() {
                var pages = [];
                var total = this.props.totalPages;
                for (var i = 1; i <= total; i++) {
                    pages.push(<Page key={i} onPageClick={this.props.onPageClick} pageNum={i} active={(this.props.currentPage == i) || false}/>);
                }
                return (
                    <div className="pagination">{pages}</div>
                );
            }
        });

        var Page = React.createClass({
            handleClick: function(e) {
                var pageNum = e.target.innerHTML;
                this.props.onPageClick(pageNum);
            },
            render: function() {
                return (
                    <a href="#" onClick={this.handleClick} className={this.props.active ? 'active' : ''}>{this.props.pageNum}</a>
                )
            }
        });

        var MovieSearchPage = React.createClass({
            getInitialState: function() {
                return {query: '', pageNum: 1, data: {results: [], total_pages: 0, total_results: 0}};
            },
            initSearch: function(query) {
                this.setState({query: query});
                this.doSearch(query, this.state.pageNum);
            },
            nextPage: function(pageNum) {
                this.setState({pageNum: pageNum});
                this.doSearch(this.state.query, pageNum);
            },
            doSearch: function(query, pageNum) {
                $.ajax({
                    url: this.props.url,
                    dataType : 'json',
                    type: 'POST',
                    data: {query: query, api_key: this.props.apiKey, page: pageNum},
                    success: function(data) {
                        this.setState({data: data});
                    }.bind(this),
                    error: function(xhr, status, err) {
                        console.error(this.props.url, status, err.toString());
                    }.bind(this)
                });
            },
            render: function() {
                return (
                    <div>
                        <SearchBar onSearch={this.initSearch}/>
                        <SearchResults onPageChange={this.nextPage} data={this.state.data}/>
                    </div>
                );
            }
        });

        ReactDOM.render(
            <MovieSearchPage url="http://api.themoviedb.org/3/search/movie" apiKey=""/>,
            document.getElementById('container')
        );
var SearchResults=React.createClass({
handlePageChange:函数(pageNum){
this.props.onPageChange(pageNum);
},
render:function(){
var=[];
this.props.data.results.forEach(函数(电影){
电影。推();
});
返回(
搜索结果({this.props.data.total_results}已找到)
{电影}
);
}
});
var SearchBar=React.createClass({
getInitialState:函数(){
返回{查询:''};
},
handleQueryChange:函数(e){
this.setState({query:e.target.value});
},
handleSubmit:函数(e){
e、 预防默认值();
var query=this.state.query.trim();
如果(!query | | query.length<3){
返回;
}
this.props.onSearch(查询);
},
render:function(){
返回(
);
}
});
var MovieBox=React.createClass({
render:function(){
var m=this.props.movie;
返回(
{m.原始标题}({m.发布日期})
);
}
});
var Pagination=React.createClass({
render:function(){
var页面=[];
var total=this.props.totalPages;

对于(var i=1;我似乎需要使用分页中相同的查询和页码调用doSearch。能否给每个数字一个onClick=“doSearch(query,THIS page number)”?我对React不太熟悉,无法给出任何代码。我在React之外做过这件事,逻辑应该是一样的。React的问题是,我认为,您不能简单地调用其他组件的方法。为此,您需要将回调方法作为参数(或React.js中调用的属性)传递到子组件。在我的应用程序中,我必须将它从父组件(基本上是页面本身)一直传递到每个页面链接。似乎您需要使用分页中相同的查询和页码调用doSearch。您能给每个数字一个onClick=“doSearch(查询,此页码)”?我对React不太熟悉,无法给出任何代码。我在React之外做过这件事,逻辑应该是一样的。React的问题是,我认为,您不能简单地调用其他组件的方法。为此,您需要将回调方法作为参数(或React.js中调用的属性)传递在我的应用程序中,我必须将它从父组件(基本上就是页面本身)一直传递到每个页面链接。