Реагировать — отправлять реквизит функции дочерним элементам

#javascript #reactjs #undefined #parent-child

#javascript #reactjs #не определено #родитель-потомок

Вопрос:

Я видел несколько вопросов, в которых говорилось о подобных проблемах, но почему-то мне все еще не удается решить мою проблему, поэтому здесь я прошу вашей любезной помощи. Я довольно новичок в React и хотел бы отправить функцию от родителя дочернему элементу, а затем использовать ее от дочернего элемента, но почему-то, когда я хочу ее использовать, она говорит

Неперехваченная ошибка типа: не удается прочитать свойство ‘props’ неопределенного»

Отредактированный код после первых ответов помог:

 var Menu = React.createClass({
    links : [
        {key : 1, name : "help", click : this.props.changePageHelp}
    ],
    render :    function() {
        var menuItem = this.links.map(function(link){
            return (
                <li key={link.key} className="menu-help menu-link" onClick={link.click}>{link.name}</li>
            )
        });
        return (
            <ul>
                    {menuItem}
            </ul>
        )
    }
});

var Admin = React.createClass ({
    _changePageHelp : function() {
        console.log('help');
    },
     render : function () {
        return (
            <div>
                <div id="menu-admin"><Menu changePageHelp={this._changePageHelp.bind(this)} /></div>
            </div>
        )
    }
});

ReactDOM.render(<Admin />, document.getElementById('admin'));
  

Комментарии:

1. Извините, я отредактировал свой пост, что я просто хочу, чтобы console.log (‘help’) активировался, чего не происходит. В приведенном ниже хорошем ответе основное внимание уделяется тому факту, что я не отправлял функции параметр, однако я просто хочу активировать функцию, и, похоже, она не работает (все еще неопределенная ошибка)

2. Хорошо, частично работает, благодаря комментарию ниже, моя проблема, похоже, в другом месте. Я также хотел в своем компоненте shild создать переменную, подобную этой: links : [ {key : 1, name : «help», click : this.props.changePageHelp} ] , и, похоже, ему это не нравится, потому что именно тогда появляется моя ошибка. Не могу ли я использовать реквизит, отправленный в переменной в моем дочернем компоненте?

3. Приведенные ниже ответы касаются некоторых ваших проблем с кодом, но на самом деле они не исправляют вашу ошибку, которая, по-видимому, связана с тем фактом, что this у нее нет prop свойства — вероятно, потому, что ссылаются на неправильное this . Попробуйте использовать функции со стрелками ES6. Это предотвратит эту головную боль.

4. Можете ли вы отредактировать свой вопрос, чтобы описать, где именно у вас возникла проблема

5. @ShubhamKhatri: только что сделал это. Идея заключалась в том, чтобы создавать ссылки через компоненты, но почему-то что-то не хочет проходить. Как и следовало ожидать, будет более одной «ссылки»

Ответ №1:

Передайте значение из функции Menu и получите его в функции changePageHelp, и это сработает.

 var Menu = React.createClass({
    render : function() {
        return (
            <div>
                {this.props.changePageHelp('Hello')}
            </div>
        )
    }
});

var Admin = React.createClass ({
    _changePageHelp : function(help) {
        return help;
    },
     render : function () {
        return (
            <div>
                <div id="menu-admin"><Menu changePageHelp={this._changePageHelp.bind(this)} /></div>
            </div>
        )
    }
});

ReactDOM.render(<Admin />, document.getElementById('admin'));  
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script>
<div id="admin"></div>  

Ответ №2:

По соображениям производительности вам следует избегать использования bind функций или стрелок в реквизите JSX. Это связано с тем, что копия функции обработки событий создается для каждого экземпляра, сгенерированного map() функцией. Это объясняется здесь: https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md

Чтобы избежать этого, вы можете перенести повторяющийся раздел в его собственный компонент. Вот демонстрация: http://codepen.io/PiotrBerebecki/pen/EgvjmZ console.log() Вызов в вашем родительском компоненте теперь получает имя ссылки. Вы могли бы использовать его, например, в маршрутизаторе React.

 var Admin = React.createClass ({
    _changePageHelp : function(name) {
      console.log(name);
    },

    render : function () {
      return (
        <div>
          <div id="menu-admin">
            <Menu changePageHelp={this._changePageHelp} />
          </div>
        </div>
      );
    }
});


var Menu = React.createClass({
  getDefaultProps: function() {
    return {
      links: [
        {key: 1, name: 'help'},
        {key: 2, name: 'about'},
        {key: 3, name: 'contact'}
      ]
    };
  },

  render: function() {
    var menuItem = this.props.links.map((link) => {
      return (
        <MenuItem key={link.key}
                  name={link.name}
                  changePageHelp={this.props.changePageHelp}
                  className="menu-help menu-link" />
      );
    });

    return (
      <ul>
        {menuItem}
      </ul>
    );
  }
});


var MenuItem = React.createClass ({
  handleClick: function() { 
    this.props.changePageHelp(this.props.name);
  },

  render : function () {
    return (
      <li onClick={this.handleClick}>
        Click me to console log in Admin component <b>{this.props.name}</b>
      </li>
    );
  }
});


ReactDOM.render(<Admin />, document.getElementById('admin'));
  

Комментарии:

1. Это сделало это, большое спасибо! Однако я до сих пор не совсем понимаю, почему другие решения не работали…