简体   繁体   English

Windows调整大小错误后的setState与react。 尝试通过动态宽度作为道具

[英]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. 尝试动态计算散点图的宽度,以便将其作为道具传递给d3组件。 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. 我在ComponentDidMount中的window.addEventListener('resize',this.handleResize)调用的handleResize函数中没有控制台登录问题,但是我无法在handleResize函数中设置state或访问其中的任何内容。 I've also tried var self = this; 我也尝试过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. 重新绑定它,但仍然得到this.setState不是函数或self.setState不是函数。

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'. handleResize没有与'this'关联的Dashboard对象。 You need to bind to the event hanler replace window.addEventListener('resize', this.handleResize); 您需要绑定到事件hanler replace window.addEventListener('resize', this.handleResize); with window.addEventListener('resize',this.handleResize.bind(this)); 使用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 它将绑定this关键字..以便您可以执行this.setState或访问仪表板中定义的任何对象

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. 如果您打算在方法内部使用this方法,并且该方法不属于react组件生命周期的一部分,则需要将其上下文设置为组件实例。 In your case you haven't set the correct context for the handleResize , getDomains , dataChangeHelper methods, so the constructor needs some additional bindings: 在您的情况下,您没有为handleResizegetDomainsdataChangeHelper方法设置正确的上下文,因此构造函数需要一些其他绑定:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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