如何将React方法赋予html组件的onClick处理程序?

时间:2018-10-30 22:54:35

标签: javascript reactjs

我正在尝试更改从数据库接收的HTML,以响应自定义的onClick处理程序。具体来说,我提取的HTML具有称为yui-navsets的div,其中包含yui_nav页面选择器和yui_content页面内容。我想单击yui_nav中的li,将li的类设置为“ selected”,将现有内容设置为display:none,然后将新内容设置为style =“”。

为此,我创建了一个updateTabs函数,该函数输入所选yui的索引和新页码,将li的类设置为“ selected”,将现有内容设置为display:none,然后设置新内容样式=“”。此功能有效:我尝试在componentDidUpdate中运行updateTabs(2,3),它工作正常,可以根据请求更改内容。我想将updateTabs分配给每个lis,并且在axios请求之后尝试在componentDidMount中进行分配。

但是,我不断收到错误消息:TypeError: this.updateTabs is not a function。请帮忙吗?

Page.js:

import React, { Component } from 'react';
import axios from 'axios';

class Page extends Component {
  constructor(props) {
    super(props);
    this.state = {
      innerHTML: "",
      pageTags: [],
    };
    console.log(this.props.url);
  }

  componentDidMount() {
    console.log(this.props.url);
    axios
      .get(
        this.props.db_address + "pages?url=" + this.props.url,
        {headers: {"Access-Control-Allow-Origin": "*"}}
      )
      .then(response => {
        this.setState({
          innerHTML: response.data[0].html,
          pageTags: response.data[1]
        });
        console.log(response);
        // Check for yui boxes, evade the null scenario
        var yui_sets = document.getElementsByClassName('yui-navset');
        if (yui_sets !== null) {
          let yui_set, yui_nav, yui_content;
          // Iterate through the navs of each set to find the active tabs
          for (var yui_set_count = 0; yui_set_count < yui_sets.length; yui_set_count ++) {
            yui_set = yui_sets[yui_set_count];
            yui_nav = yui_set.getElementsByClassName('yui-nav')[0].children;
            yui_content = yui_set.getElementsByClassName('yui-content')[0].children;
            let tab_count;
            // Give each nav and tab and appropriate ID for testing purposes
            for (tab_count = 0; tab_count < yui_nav.length; tab_count ++) {
              yui_nav[tab_count].onclick = function() { this.updateTabs(yui_set_count); }
              yui_nav[tab_count].id = "nav-"+ yui_set_count.toString() + "-" + tab_count.toString()
              yui_content[tab_count].id = "content-"+ yui_set_count.toString() + "-" + tab_count.toString()
            }
          }
        }
      })
      .catch(error => {
        this.setState({ innerHTML: "ERROR 404: Page not found." })
        console.log(error);
      });
  }

  updateTabs(yui_index, tab_index){
    // Get all yuis
    var yui_sets = document.getElementsByClassName('yui-navset');
    let yui_set, yui_nav, yui_content
    yui_set = yui_sets[yui_index];
    yui_nav = yui_set.getElementsByClassName('yui-nav')[0].children;
    yui_content = yui_set.getElementsByClassName('yui-content')[0].children;
    // Identify the current active tab
    var current_tab_found = false;
    var old_index = -1;
    while (current_tab_found == false) {
      old_index += 1;
      if (yui_nav[old_index].className === "selected") {
        current_tab_found = true;
      }
    }
    // Identify the new and old navs and contents
    var yui_nav_old = yui_nav[old_index]
    var yui_nav_new = yui_nav[tab_index]
    var yui_content_old = yui_content[old_index]
    var yui_content_new = yui_content[tab_index]
    // Give the new and old navs and contents their appropriate attributes
    yui_nav_old.className = "";
    yui_nav_new.className = "selected";
    yui_content_old.style = "display:none";
    yui_content_new.style = "";
  }

  render() {
    return (
      <div className="Page">
        <div className="Page-html col-12" dangerouslySetInnerHTML={{__html:this.state.innerHTML}} />
        <div className="Page-footer">
          <div className="d-flex flex-wrap btn btn-secondary justify-content-around">
            {this.state.pageTags.map(function(pageTag){return(
              <div className="pd-2" key={pageTag.id}>
                {pageTag.name}
              </div>
            )})}
          </div>
          <div className="d-flex justify-content-center" >
            <div className="p-2">Discuss</div>
            <div className="p-2">Rate</div>
            <div className="p-2">Edit</div>
          </div>
          <div className="d-flex justify-content-around App">
            <div className="p-2">
              Unless otherwise stated, the content
              of this page is licensed under <br />
              <a href="http://creativecommons.org/licenses/by-sa/3.0/"
              target="_blank" rel="noopener noreferrer">
                Creative Commons Attribution-ShareAlike 3.0 License
              </a>
            </div>
          </div>
        </div>
      </div>
    )
  }
}

export default Page

2 个答案:

答案 0 :(得分:1)

使用箭头功能代替带有功能关键字的功能,将按以下方式解决

您有

yui_nav[tab_count].onclick = function() { this.updateTabs(yui_set_count); }

但是使用

yui_nav[tab_count].onclick = () => { this.updateTabs(yui_set_count); }

在componentDidMount方法中使用此

答案 1 :(得分:0)

  1. 您必须在构造函数中绑定updateTabs方法:

constructor(props) { super(props); ... this.updateTabs = this.updateTabs.bind(this); }

  1. 您应该使用箭头函数,以使用正确的contetxt调用此方法:

yui_nav[tab_count].onclick = () => { this.updateTabs(yui_set_count); }