无法读取null React的属性'style'

时间:2019-01-14 11:52:04

标签: javascript css reactjs

当我使用以下代码为侧栏添加组件时,我是新来的反应:

  

无法读取null的属性“样式”

import React, { Component } from "react";
import "../css/sidebar.css";

class Sidebar extends Component {
  state = {};

  openNav() {
    document.getElementById("mySidenav").style.width = "250px";
    document.getElementById("main").style.marginLeft = "250px";
  }

  closeNav() {
    document.getElementById("mySidenav").style.width = "0";
    document.getElementById("main").style.marginLeft = "0";
  }

  render() {
    return (
      <div>
        <div id="mySidenav" class="sidenav">
          <a
            href="javascript:void(0)"
            class="closebtn"
            onclick={this.closeNav()}
          >
            &times;
          </a>
          <a href="#">About</a>
          <a href="#">Services</a>
          <a href="#">Clients</a>
          <a href="#">Contact</a>
        </div>

        <div id="main">
          <h2>Sidenav Push Example</h2>
          <p>
            Click on the element below to open the side navigation menu, and
            push this content to the right.
          </p>
          <span
            styles={{ fontSize: "30", cursor: "pointer" }}
            onclick={this.openNav()}
          >
            &#9776; open
          </span>
        </div>
      </div>
    );
  }
}

export default Sidebar;

下面的部分有错误吗?

document.getElementById("mySidenav").style.width = "0";

出什么问题了?

如果有人可以帮助的话,将非常可观。

7 个答案:

答案 0 :(得分:2)

您正在尝试使用Vanilla JS环境中的反模式来获取DOM Node上的链接。有关引用的用法,请参见React docs

由于React具有自己的DOM导航环境,因此您只能使用它。像下面这样更新代码:

import React, { Component } from "react";
import "../css/sidebar.css";

class Sidebar extends Component {
  constructor(props){
      super(props)

      this.state = {}

      this.mySidenav = React.createRef()
      this.main = React.createRef()
  }

  openNav() {
    this.mySidenav.current.style.width = "250px";
    this.main.current.style.marginLeft = "250px";
  }

  closeNav() {
    this.mySidenav.current.style.width = "0";
    this.main.current.style.marginLeft = "0";
  }

  render() {
    return (
      <div>
        <div id="mySidenav" ref={this.mySidenav} class="sidenav">
          <a
            href="javascript:void(0)"
            class="closebtn"
            onclick={this.closeNav}
          >
            &times;
          </a>
          <a href="#">About</a>
          <a href="#">Services</a>
          <a href="#">Clients</a>
          <a href="#">Contact</a>
        </div>

        <div id="main" ref={this.main}>
          <h2>Sidenav Push Example</h2>
          <p>
            Click on the element below to open the side navigation menu, and push this content to the right.
          </p>
          <span
            styles={{ fontSize: "30", cursor: "pointer" }}
            onclick={this.openNav}
          >
            &#9776; open
          </span>
        </div>
      </div>
    );
  }
}

答案 1 :(得分:1)

编写onclick={this.openNav()}时,您将调用一个函数而不是将其传递给prop。 它在组件安装之前在渲染阶段中调用,因此您的元素不存在。 要修复它,您应该传递一个函数。只需:

onclick={this.openNav}
onclick={this.closeNav}

答案 2 :(得分:1)

首先,在完全加载DOM之前,无法访问document元素,因此您需要检查该元素是否已加载:

class Sidebar extends React.Component {
  state = {};

  //Here you are not binding your methods nor you are using the ES6 Arrow function so you need to change the code here also.
  openNav = () => {
    if (
      document.getElementById("mySidenav") &&
      document.getElementById("main")
    ) {
      document.getElementById("mySidenav").style.width = "250px";
      document.getElementById("main").style.marginLeft = "250px";
    }
  };

  closeNav = () => {
    if (
      document.getElementById("mySidenav") &&
      document.getElementById("main")
    ) {
      document.getElementById("mySidenav").style.width = "0";
      document.getElementById("main").style.marginLeft = "0";
    }
  };

  render() {
    return (
      <div>
        <div id="mySidenav" class="sidenav">
           //Here you are calling the function on initial render that is why you are getting the error. you need to pass the function like this in order to trigger it on an event.
          <a href="javascript:void(0)" class="closebtn" onclick={this.closeNav}>
            &times;
          </a>
          <a href="#">About</a>
          <a href="#">Services</a>
          <a href="#">Clients</a>
          <a href="#">Contact</a>
        </div>

        <div id="main">
          <h2>Sidenav Push Example</h2>
          <p>
            Click on the element below to open the side navigation menu, and
            push this content to the right.
          </p>
          <span
            styles={{ fontSize: "30", cursor: "pointer" }}
            //Same as above here also
            onclick={this.openNav}
          >
            &#9776; open
          </span>
        </div>
      </div>
    );
  }
}

已更正的部分将是这个。 您应该看到有关ES6和类的一些概念。

答案 3 :(得分:0)

使用document.getElement...似乎是一种反模式-有关refs的用法,请参见docs

引用提供了一种访问DOM节点或在render方法中创建的React元素的方法。

您可能还希望跟踪state中的宽度,以便可以使用setState更新宽度,并使JSX中的style属性在状态中反映出这些宽度

答案 4 :(得分:0)

不要直接调用方法,而要传递方法引用。

尝试将onclick={this.openNav()}更改为onClick={this.openNav}

onclick={this.closeNav()}onClick={this.closeNav}

,您的JSX代码不在render()方法内。试试这个:

render() {
  return (

  <div>
    <div id="mySidenav" className="sidenav">
      <a href="javascript:void(0)" className="closebtn" onClick="{this.closeNav}">
        ×
      </a>
      <a href="#">About</a>
      <a href="#">Services</a>
      <a href="#">Clients</a>
      <a href="#">Contact</a>
    </div>
    <div id="main">
      <h2>Sidenav Push Example</h2>
      <p>
        Click on the element below to open the side navigation menu, and
        push this content to the right.
      </p>
      <span style={{ fontsize: '30', cursor: 'pointer' }} onClick="{this.openNav}">
        &#9776; open
      </span>
    </div>
  </div>
 );
}

答案 5 :(得分:0)

作为我在原始帖子下的评论,不建议您以这种方式添加样式。您应该改用state。对于您的问题,这是您的绑定问题,应该这样

 <a href="javascript:void(0)"
    class="closebtn"
    onclick={this.closeNav}
 >

其他元素也是如此

答案 6 :(得分:0)

在加载DOM之前,无法访问

document元素,因此您需要检查元素是否已加载

    if (
  document.getElementById("mySidenav") &&
  document.getElementById("main")
) {
  document.getElementById("mySidenav").style.width = "250px";
  document.getElementById("main").style.marginLeft = "250px";
}

或使用钩子-useEffect()

useEffect(() => {
  document.getElementById("togBtn").style.cursor = "pointer";
   }, []);