Как исправить «используется обратное() для отображения через данные тянули из API вызова (хранится в Redux состоянии) [Javascript Redux/React]»

Вопрос задан: 8 месяцев назад Последняя активность: 8 месяцев назад
up 0 down

this.props.playedGames тянет из моего Redux государства и упорядочена последняя дата на первую запись (в убывающем порядке). Мне нужны данные для моей кумулятивной диаграммы линии (chart.js), чтобы быть в первой записи обратного порядка наиболее поздней дату. Как бы я сделать это без использования обратного метода, который постоянно переворачивает при каждом обновлении. Я не хотел бы повторно вызвать API, как у меня есть данные, что мне нужно.

Я попытался создать государство для того, когда страница обновляется, поэтому он не будет обновляться. Я попробовал несколько различных способов этого. Все не удалось.

мой код:

import { connect } from 'react-redux';
import {withRouter} from 'react-router';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import {Line} from 'react-chartjs-2';

class ChartPage extends Component {
profitForChart = (props) => {
    let total = 0
    return this.props.playedGames.reverse().map( (game, index) => ({
      x: index,
      y: total += parseFloat(game.profit)

    }))
  } 
render() {
   if(!this.props.playedGames) return <h1>Loading...</h1>
    const { classes } = this.props;
    const data = {
      datasets: [{
        data: this.profitForChart(),
        label: 'PROFIT'
    }],
    labels: this.props.playedGames.map( game => (new Date(game.start_date_time)).toLocaleDateString()),
  }
  return(
      <div className={classes.root}

            <Line data={data} />

      </div>
  )
 }
}
const mapStateToProps = ( state ) => {
  return {
    playedGames: state.userPlayedGames.playedGames,
    isLoading: state.isLoading,
  }
}
const mapDispatchToProps = {
}
ChartPage.propTypes = {
  classes: PropTypes.object.isRequired,
};
export default  compose(
  withStyles(styles, {
    name: 'ChartPage',
  }),
  connect(mapStateToProps, mapDispatchToProps))(withRouter(ChartPage));

Ожидаемый результат: 1/2018, 2/2018, 3/2018 с накопительным линейным графиком идет вверх в течение долгого времени.

Фактический результат: (Правильно на начальной загрузки и любого другого обновления), но следующий не так: граф кумулятивный является обратным и даты идти в обратном направлении: 3/2018, 2/2018, 1/2018. -----

4 ответа

up 0 down

Вы можете использовать static getDerivedStateFromProps(props, state) жизнь метод Lifecycle обратить свои «playedGames» только реквизит на самом деле вместо реверса на каждом обновлении.

static getDerivedStateFromProps(props, state) {
    // Any time the playedGames changes,
    // Reverse and store in the state
    if (props.playedGames !== state.playedGames) {
        const dataForChart = props.playedGames.reverse().map((game, index) => ({
            x: index,
            y: (total += parseFloat(game.profit)),
        }));

        return {
            dataForChart: dataForChart,
            playedGames: playedGames,
        };
    }

    return null;
}

Затем используйте отсортированные данные в состоянии построить график. (this.state.dataForChart)

up 0 down

Пусть предположим апи дает следующий ответ,

const response = [{x: 3, y: 5, date: '1/2/2018'}, {x: 3, y: 5, date: '1/4/2019'}, {x: 3, y: 5, date: '1/4/2013'}, {x: 3, y: 5, date: '1/2/2016'}]

Теперь мы можем сортировать это по дате, используя функцию сортировки.

response
   .sort((a,b) => new Date(a.date) > new Date(b.date) ? -1 : 0)
   .map(// use your above code)
up 0 down

Я нашел ответ, используя .splice() обратный(), как показано ниже.:

import { connect } from 'react-redux';
import {withRouter} from 'react-router';
import { Link } from 'react-router-dom';
import PropTypes from 'prop-types';
import {Line} from 'react-chartjs-2';

class ChartPage extends Component {
profitForChart = (props) => {
    let total = 0
    return this.props.playedGames.slice().reverse().map( (game, index) => ({
      x: index,
      y: total += parseFloat(game.profit)

    }))
  } 
render() {
   if(!this.props.playedGames) return <h1>Loading...</h1>
    const { classes } = this.props;
    const data = {
      datasets: [{
        data: this.profitForChart(),
        label: 'PROFIT'
    }],
    labels: this.props.playedGames.slice().reverse().map( game => (new Date(game.start_date_time)).toLocaleDateString()),
  }
  return(
      <div className={classes.root}

            <Line data={data} />

      </div>
  )
 }
}
const mapStateToProps = ( state ) => {
  return {
    playedGames: state.userPlayedGames.playedGames,
    isLoading: state.isLoading,
  }
}
const mapDispatchToProps = {
}
ChartPage.propTypes = {
  classes: PropTypes.object.isRequired,
};
export default  compose(
  withStyles(styles, {
    name: 'ChartPage',
  }),
  connect(mapStateToProps, mapDispatchToProps))(withRouter(ChartPage));
up 0 down

reverse() (Ые также sort()) Является функцией на месте, а это означает, что изменить содержимое массива, назвав его. Это идет вразрез с РЕАКТОМ неизменного идеологии, где Данные не должны быть изменены после того, как они создаются.

Я предлагаю вам клонировать массив (и обратный клонированный массив) перед передачей его в реквизит компонента:

const mapStateToProps = ( state ) => {
  return {
    playedGames: state.userPlayedGames.playedGames.slice().reverse(),
    isLoading: state.isLoading,
  }
}