Reactjs组件显示旧数据

spe*_*son 1 javascript reactjs react-redux

我有一个应该显示项目列表的组件。首次加载组件时,将从API提取项目,然后应在用户单击按钮时刷新/替换项目。

问题是,我的组件似乎总是落后于用户一步。例如,用户第一次单击该按钮时,将调用API并返回新数据,但是该组件仍显示其在初始加载时获得的数据。用户第二次单击时,我的组件将显示第一次单击时返回的数据。

我认为单击按钮后即可快速将组件重新加载,因此显示组件时状态不会更新,但是我不知道如何解决?

我的组件:

import React, {Component} from 'react';
import {connect} from 'react-redux';
import {matchesFetchData} from '../actions/matches';
import Match from './match';


class MatchList extends Component {
    constructor(){
        super();
        this.generateNew = this.generateNew.bind(this);
    }  

    componentDidMount() {
        this.props.fetchData('http://localhost:4752/api/matches');
    }

    render() {
        if (this.props.hasErrored) {
            return <p>Sorry!There was an error loading the items</p>;
        }
        if (this.props.isLoading) {
            return <p>Loading…</p>;
        }

        return (   
            <div>
                <nav className="menu">
                    <input type="number" defaultValue="0" min="0" max="13" ref="safeguards"/>      
                    <button className="generateNew" onClick={this.generateNew}>Ny</button>         
                </nav>
                <ul className="matchlist">
                    {this.props.matches.map(function (match, index) {                        
                        return <Match key={index} match={match}/>
                    }) }
                </ul>
            </div>
        )
    }

    generateNew(e){
        e.preventDefault();
        const value = this.refs.safeguards.value;
        if(value == 0){
            this.props.fetchData('http://localhost:4752/api/matches');
        }
        else{
            this.props.fetchData('http://localhost:4752/api/matches/' + value);
        }
    }
}

const mapStateToProps = (state) => {
    return {
        matches: state.matchesApp.matches,
        hasErrored: state.matchesApp.matchesHasErrored,
        isLoading: state.matchesApp.matchesIsLoading
    };
};


const mapDispatchToProps = (dispatch) => {
    return {
        fetchData: (url) => dispatch(matchesFetchData(url))
    };
};  

export default connect(mapStateToProps, mapDispatchToProps)(MatchList);
Run Code Online (Sandbox Code Playgroud)

动作:

export const MATCHES_HAS_ERRORED = 'MATCHES_HAS_ERRORED';
export const MATCHES_IS_LOADING = 'MATCHES_IS_LOADING';
export const MATCHES_FETCH_DATA_SUCCESS = 'MATCHES_FETCH_DATA_SUCCESS';

export function matchesHasErrored(bool){
    return {
        type: MATCHES_HAS_ERRORED,
        hasErrored: bool
    };
}

export function matchesIsLoading(bool){
    return {
        type: MATCHES_IS_LOADING,
        isLoading: bool
    };
}

export function matchesFetchDataSuccess(matches){
    return{
        type: MATCHES_FETCH_DATA_SUCCESS,
        matches
    };
}

export function matchesFetchData(url){
    return (dispatch) => {
        dispatch(matchesIsLoading(true));

        fetch(url)
        .then((response) => {
            if(!response.ok){
                throw Error(response.statusText);
            }

            dispatch(matchesIsLoading(false));

            return response;
        })
        .then((response) => response.json())
        .then((matches) => dispatch(matchesFetchDataSuccess(matches)))
        .catch(() => dispatch(matchesHasErrored(true)));
    }
}
Run Code Online (Sandbox Code Playgroud)

减速器:

import {MATCHES_HAS_ERRORED, MATCHES_IS_LOADING, MATCHES_FETCH_DATA_SUCCESS} from '../actions/matches';

const initialState = {
    matchesIsLoading: false,
    matchesHasErrored: false,
    matches: []
}

export function matchesApp(state = initialState, action){
    switch(action.type){
      case MATCHES_HAS_ERRORED:
            return Object.assign({}, state, {
                matchesHasErrored: action.hasErrored
            });
      case MATCHES_IS_LOADING:
            return Object.assign({}, state, {
                matchesIsLoading: action.isLoading
            });
      case MATCHES_FETCH_DATA_SUCCESS:
            return Object.assign({}, state, {
                matchesIsLoading: false,
                matchesHasErrored: false,
                matches: action.matches
            });
      default:
            return state;
    }
}
Run Code Online (Sandbox Code Playgroud)

匹配组件:

import React, {Component} from 'react';
import {Link} from 'react-router-dom';
import Result from './result';

class Match extends Component {
    constructor(props){
        super(props);
        this.match = this.props.match;
    }    

    render() {
        return (
            <li>
                <Link to={'/' + this.match.home + '/' + this.match.away}>
                    <span className="matchNumber">{this.match.number}</span>
                    <span className="matchup">
                        {this.match.home} - {this.match.away}
                    </span>
                    <Result value="1" selected={this.match.homeWin} odds={this.match.percent1}/><Result value="X" selected={this.match.draw} odds={this.match.percentX}/><Result value="2" selected={this.match.awayWin} odds={this.match.percent2}/>
                </Link>
            </li>
        )
    }
}

export default Match;
Run Code Online (Sandbox Code Playgroud)

ngr*_*grn 6

根据组件的外观,传递给您的key属性可能会出现问题,在这种情况下,如果comes的显示值来自状态,则该组件不会被完全删除,因此将显示陈旧数据