简体   繁体   中英

setState after windows resize error with react. Trying to pass dynamic width as props

Trying to calculate width of my scatterplot on the fly so I can pass it as props to my d3 component. I'm having no problem console logging in the handleResize function that is being called by window.addEventListener('resize', this.handleResize) in my ComponentDidMount but I can't setState in the handleResize function or seem to access anything outside of it. I've also tried var self = this; to rebind it but am still getting either a this.setState is not a function or self.setState is not a function.

import React, { PropTypes, Component } from 'react';
import { getDataRange, getTeams, getFile, getAllHitsData, getPlayers} from 'api/index.js';
import {Table, Thead, Th, Tr, Td} from 'components/Reactable';
import Autosuggest from 'react-autosuggest';
import { Link } from 'react-router';
import ScatterChart from 'components/scatterchart';
import DashboardStats from 'components/dashboard-stats';
import DateRangeComponent from 'components/date-range';
import AdminSquare from 'components/admin-square';
import { connect } from 'react-redux';
import { changeStartDate, changeEndDate } from '../../redux/modules/redux-date-change';
import { sendHitData } from '../../redux/modules/send-hit.js';
import { Loading } from 'react-loading';

let allHitDatas = [];
let hitDatas = [];
let teams = [];
// let selectedTeamID = null;
// let selectedTeamName = 'all_teams';
let newFile = '';
// let teamId = '';
let players = [];
let width;

class Dashboard extends Component {
    static propTypes = {
       team: PropTypes.object.isRequired,
       startDate: PropTypes.string.isRequired,
       endDate: PropTypes.string.isRequired,
       dispatch: PropTypes.func.isRequired
    };
    static contextTypes = {
        router: PropTypes.object
    };
    constructor(props, context) {
        super(props, context);
        this.state = {
            showRangePicker: false,
            hitDatas: [],
            teams: [],
            start: "",
            end: "",
            team: this.props.team,
            selectedTeamID: null,
            selectedTeamName: "",
            newFileConfirmation: false,
            players: [],
            allHitDatas: [],
            suggestions: this.getSuggestions(''),
            selected: '',
            showDatePickerControls: false,
            // maxHic: 0
            // showScatterPlot: true
        };
        this.onChange = this.onChange.bind(this);
        this.onSuggestionsUpdateRequested = this.onSuggestionsUpdateRequested.bind(this);
    }

    componentWillReceiveProps() {
        this.setState({
           maxHic: 0,
           team: this.props.team,
           selectedTeamID: this.props.team.id,
           startDate: this.props.startDate,
           endDate: this.props.endDate
        //    allHitDatas: []
       }, () => {
        //    this.getDomains();
           this.dataChangeHelper();
           return this.state;
       });
    }

      componentDidMount() {
         this.dataChangeHelper();
         window.addEventListener('resize', this.handleResize);

         getTeams().then((response) => {
             teams = response.data;
             this.setState({teams: teams});
         });

         getPlayers().then((response) => {
             players = response.data;
             this.setState({
                 players: players
             }, () => {
                     return this.state;
             });
         });
      }

    getDomains() {
        let dates = [];
        let hicArray = [];
        console.log(this.state.allHitDatas);
        if (this.state.allHitDatas.length === 0) {
            return allHitDatas.map((hitData) => {
                let date = Date.parse(hitData.EventTime);
                dates.push(date);
                hicArray.push(hitData.Hic);
                let maxDate = Math.max.apply(null, dates);
                let maxHic = 0;
                let minDate = Math.min.apply(null, dates);
                let minHic = 0;
                this.setState({
                    minDate: minDate,
                    maxDate: maxDate,
                    minHic: minHic,
                    maxHic: maxHic
                }, () => {
                    console.log(this.state.maxHic);
                    return this.state;
                });
              });
        }
        return this.state.allHitDatas.map((hitData) => {
            let date = Date.parse(hitData.EventTime);
            dates.push(date);
            hicArray.push(hitData.Hic);
            let maxDate = Math.max.apply(null, dates);
            let maxHic = Math.max.apply(null, hicArray);
            let minDate = Math.min.apply(null, dates);
            let minHic = Math.min.apply(null, hicArray);
            this.setState({
                minDate: minDate,
                maxDate: maxDate,
                minHic: minHic,
                maxHic: maxHic
            }, () => {
                console.log(this.state.maxHic)
                return this.state;
            });
        });
    }

    dataChangeHelper() {
          const newConfig = {
            start: this.props.startDate,
            end: this.props.endDate,
            team: this.props.team.id
          };

          getDataRange(newConfig)
          .then((response) => {
            hitDatas = response.data;
            this.setState({
              hitDatas: hitDatas
              }, () => {
                  return this.state;
              });
          });
          getAllHitsData(newConfig)
          .then((response) => {
            allHitDatas = response.data;
            this.setState({
              allHitDatas: allHitDatas
              }, () => {
                  this.getDomains();
                  return this.state;
              });
          });
    }

    handleResize() {
        // const self = this;
        let elem = document.getElementById('scatter-chart');
        width = elem.offsetWidth * 0.9;
        console.log(width);
        this.setState({
            scatterWidth: width
        }, () => {
            console.log(this.state.scatterWidth);
        });
    }


  render () {
    if (this.state.teams.length === 0 || this.state.players.length === 0) {
        return (
            <div className="no-data-container">
                <div className="no-data-message">We don't have any data for you right now. Would you like
                    to add some players, teams, or devices?
                </div>
                <ul className="no-data-links">
                    <AdminSquare title="PLAYER ADMIN" icon="person" link="/player"/>
                    <AdminSquare title="TEAM ADMIN" icon="group" link="/team"/>
                    <AdminSquare title="DEVICE ADMIN" icon="sd_storage" link="/device"/>
                </ul>
            </div>
        );
    }

    const { value, suggestions } = this.state;
    const inputProps = {
      placeholder: 'Search for a player',
      value,
      onChange: this.onChange
    };

    return (
        <div>

                     <ScatterChart
                     data={this.state.allHitDatas}
                     domain={{x: [this.state.minDate, this.state.maxDate], y: [this.state.maxHic, 0]}}
                     statOneTitle="HIC"
                     sendHitData={(d) => this.handleImpactClick(d)}
                     width={ width }
                     />
         </div>
        );
      }
    }

    function mapStateToProps(state) {
        console.log(state);
        return {
            startDate: state.startDate,
            endDate: state.endDate
        };
    }

    export default connect(mapStateToProps)(Dashboard);

handleResize doesn't have Dashboard object associated with 'this'. You need to bind to the event hanler replace window.addEventListener('resize', this.handleResize); with window.addEventListener('resize',this.handleResize.bind(this));

which will bind the this keyword..so that you can do like this.setState or access any object defined in Dashboard

If you plan on using this inside of a method and the method is not a part of react component's lifecycle , then you need to set it's context to the component instance. In your case you haven't set the correct context for the handleResize , getDomains , dataChangeHelper methods, so the constructor needs some additional bindings:

this.handleResize = this.handleResize.bind(this); getDomains ... dataChangeHelper ...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM