如何根据下拉列表中的选择更新网页?

时间:2018-06-01 22:35:56

标签: javascript reactjs sorting redux updates

我有一个显示API电影列表的网页。正如您在我的代码中看到的那样,在render方法下我有三个注释掉的排序方法,当我取消注释其中一个方法时,它可以正常排序。

我想要发生的是,当用户点击选择下拉列表中的某个选项时,它会相应地更新网页。

我认为onClick上的其中一个选项可以做到,但它不起作用。我现在的猜测是它与我在页面加载时显示的映射内容有关,但我不完全确定。

这是我的代码:

import React, {Component} from "react";
import {connect} from "react-redux";
import {crimeGenre} from "./redux";

class CrimeGenre extends Component {
    constructor(){
        super();
    }

    componentDidMount(){
        this.props.crimeGenre();
    }

    sortAlpha = () => {
        return this.props.select && this.props.select.sort((a, b) => {
            a.title < b.title ? -1 : 1;
        });
    }

    render(){
        // this.props.select && this.props.select.sort((a, b) => {
        //     return a.title < b.title ? -1 : 1;
        // });

        // this.props.select && this.props.select.sort((a, b) => {
        //     return a.vote_average > b.vote_average ? -1 : 1;
        // });

        // this.props.select && this.props.select.sort((a, b) => {
        //     return a.popularity > b.popularity ? -1 : 1;
        // });
        const mappedSelected = this.props.select && this.props.select.map((film, i) => { 
            return (
                <div>
                    <h1>{film.title}</h1>
                    <img src={`http://image.tmdb.org/t/p/w185${film.poster_path}`}/>
                    <p>Avg. User Score: {film.vote_average}</p>
                </div>
            )
        })

        return(
            <div>
            <select>
                <option onClick={this.sortAlpha}>Alphabetically</option>
                <option>User Score</option>
                <option>Popularity</option>
            </select>
                {mappedSelected}
            </div>
        )
    }
}

export default connect(state=> state, {crimeGenre})(CrimeGenre);

更新:这是我的当前代码

import React, {Component} from "react";
import {connect} from "react-redux";
import {crimeGenre} from "./redux";

class CrimeGenre extends Component {
    constructor(){
        super();

        this.state = {
            value: "alphabetically"
        }
    }

    componentDidMount(){
        this.props.crimeGenre();
    }

    sortFilms = (event) => {
        this.setState({
            value: event.target.value
        })
        if(this.state.value === "alphabetically"){
            return this.props.select && this.props.select.sort((a, b) => {
                return a.title < b.title ? -1 : 1;
            });
        }else if(this.state.value === "score"){
            return this.props.select && this.props.select.sort((a, b) => {
                return a.vote_average > b.vote_average ? -1 : 1;
            });
        }else if(this.state.value === "popularity"){
            return this.props.select && this.props.select.sort((a, b) => {
                return a.popularity > b.popularity? -1 : 1;
            });
        }
    }

    render(){
        const mappedSelected = this.props.select && this.props.select.map((film, i) => { 
            return (
                <div key={i}>
                    <h1>{film.title}</h1>
                    <img src={`http://image.tmdb.org/t/p/w185${film.poster_path}`}/>
                    <p>Avg. User Score: {film.vote_average}</p>
                    <p>Popularity Index: {film.popularity.toFixed(0)}</p>
                </div>
            )
        })

            return(
                <div>
                <form>
                    <label>
                        Sort By:
                        <select value={this.state.value} onChange={this.sortFilms}>
                            <option id="alphabetically" value="alphabetically">Alphabetically</option>
                            <option id="score" value="score">User Score</option>
                            <option id="popularity" value="popularity">Popularity</option>
                        </select>
                    </label>
                </form>
                    {mappedSelected}
                </div>
            )
        }
    }

export default connect(state=> state, {crimeGenre})(CrimeGenre);

1 个答案:

答案 0 :(得分:0)

现在看来你已经接近了一个有效的解决方案。我可以推荐这个修复一些小问题的代码:

import React, {Component} from "react";
import {connect} from "react-redux";
import {crimeGenre} from "./redux";

class CrimeGenre extends Component {
    constructor(props){
        super(props);

        // Do not use component's STATE if you are using REDUX, use redux state container
        this.state = {
            value: "alphabetically"
        };
    }

    componentDidMount(){
        this.props.crimeGenre();
    }

    setOrder = (event) => {
        const value = event.target.value; // Save static value here, event may change
        this.setState({value}); // Asynchronous, `this.state.value` is not updated yet
    }

    render(){
        let mappedSelected = [];

        if (this.props.select) {
            // `this.state.value` is now updated, sort `props` accordingly
            switch (this.state.value) {
            case "alphabetically":
                this.props.select.sort((a, b) => (a.title < b.title ? -1 : 1));
                break;
            case "score":
                this.props.select.sort((a, b) => (a.vote_average > b.vote_average ? -1 : 1));
                break;
            case "popularity":
                this.props.select.sort((a, b) => (a.popularity > b.popularity? -1 : 1));
                break;
            }

            mappedSelected = this.props.select.map((film) => { 
                return (
                    // Never use index as key
                    <div key={film.poster_path}>
                      <h1>{film.title}</h1>
                      <img src={`http://image.tmdb.org/t/p/w185${film.poster_path}`}/>
                      <p>Avg. User Score: {film.vote_average}</p>
                      <p>Popularity Index: {film.popularity.toFixed(0)}</p>
                    </div>
                );
            });
        }

        return(
            <div>
              <form>
                <label>
                  Sort By:
                  <select value={this.state.value} onChange={this.setOrder}>
                    <option id="alphabetically" value="alphabetically">Alphabetically</option>
                    <option id="score" value="score">User Score</option>
                    <option id="popularity" value="popularity">Popularity</option>
                  </select>
                </label>
              </form>
              {mappedSelected}
            </div>
        );
    }
}

export default connect(state=> state, {crimeGenre})(CrimeGenre);

要解决的最后一点是您使用Redux。这是一个纯粹的React解决方案。如果仍有可能,我建议您在开始集成Redux之前给自己一些时间来理解React。