Реагировать на изменения реквизита контейнера, вызывая Uncaught TypeError: Невозможно прочитать свойство undefined - PullRequest
0 голосов
/ 02 июня 2018

У меня есть контейнер, который имеет доступ к состоянию Redux и отображает определенные фрагменты этого состояния в свои реквизиты, интересующий меня фрагмент - «монеты», поэтому

this.props.coins

Используя console.log (), я вижу, что при рендеринге контейнера у меня есть доступ к этому фрагменту состояния.

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

onClickHandler () && coinData

Контейнер имеет функцию для обработки обратного вызова под названием

_handleClick ()

В этой функции по какой-то причине this.props не предоставляет доступ кте же монеты, к которым я смог получить доступ в функции рендеринга, но у которых есть доступ к реквизиту, который я передаю компоненту, реквизиты, которые, как я думал, будут принадлежать компоненту.Итак, из _handleClick () в контейнере у меня есть доступ к

this.props.onClickHandler () && this.props.coinData

, но не

this.props.coins

Это то, к чему я ожидал получить доступ из любой точки моего контейнера.Я получаю сообщение об ошибке в заголовке поста, когда пытаюсь получить доступ к this.props.coins в моем обработчике обратного вызова _handleClick (), но почему и почему у меня есть доступ к реквизитам, которые должны принадлежать соответствующему дочернему компоненту?Есть ли способ получить доступ к this.props.coins из вызова _handleClick ()?

Мой контейнер:

import React, { Component } from 'react';
import '../App.css';
import { connect } from "react-redux";
import ChartSelectMenu from '../components/ChartSelectMenu';
import { selectCoinForChart } from '../actions/index';

class ChartSelectMenuContainer extends Component {
  constructor(props) {
    super(props);
  }

  _handleClick(ticker) {
    //event.preventDefault();
    console.log("Clicked: ", ticker);
    console.log("coin_list: ", this.props);

    const coin_list = this.props.coins;
    //
    for (let i=0; i<coin_list.length; i++) {
      if (coin_list[i].ticker === ticker) {
        this.props.dispatch(selectCoinForChart(ticker));
      }
    }
  }

  render() {
    console.log("Container props on render(): ", this.props);
      return (
        <ChartSelectMenu
        onClickHandler={this._handleClick}
        coinData={this.props.coins}
        />
      );
  }
}

function mapStateToProps({ auth, coins, selectedCoin }) {
  return { auth, coins, selectedCoin };
}

export default connect(mapStateToProps)(ChartSelectMenuContainer);

Это компонент:

import React, {Component} from 'react';
import Paper from 'material-ui/Paper';
import Menu from 'material-ui/Menu';
import MenuItem from 'material-ui/MenuItem';

const style = {
  display: 'inline-block',
  margin: '16px 0px 16px 0px',
};

class ChartSelectMenu extends Component {
  constructor(props) {
    super(props);
    }

  _renderMenuItems() {
    if (this.props === null) {
      return <h3>Loading...</h3>;
    } else {
      return(this.props.coinData.map((coin) => {
        return <MenuItem
          key={coin.ticker}
          onClick={this.props.onClickHandler.bind(this, coin.ticker)}
          primaryText={coin.ticker}
        />
      }));
    }
  }
  render() {
    //console.log('ChartSelectMenu props: ', this.props);
    return (
      <div>
        <Paper style={style}>
          <Menu>
            <ul>
              {this._renderMenuItems()}
            </ul>
          </Menu>
        </Paper>
      </div>
    )
  }
}

export default ChartSelectMenu;

1 Ответ

0 голосов
/ 02 июня 2018

Когда @MukulSharma прокомментировал «используйте var self = this внутри вашей функции», я попытался связать функцию _handleClick в конструкторе контейнера, и это сработало.

Решение:

import React, { Component } from 'react';
import '../App.css';
import { connect } from "react-redux";
import ChartSelectMenu from '../components/ChartSelectMenu';
import { selectCoinForChart } from '../actions/index';


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

    this._handleClick = this._handleClick.bind(this);
  }

  _handleClick(ticker) {
    //event.preventDefault();
    console.log("Clicked: ", ticker);
    console.log("coin_list: ", this.props);

    const coin_list = this.props.coins;
    //
    for (let i=0; i<coin_list.length; i++) {
      if (coin_list[i].ticker === ticker) {
        this.props.dispatch(selectCoinForChart(ticker));
      }
    }
  }

  render() { ...
...