【问题标题】:What is the best way to define/initialize a variable after DOM has loaded in React?在 React 中加载 DOM 后定义/初始化变量的最佳方法是什么?
【发布时间】:2021-05-20 21:12:03
【问题描述】:

我正在尝试在 React 中创建一个输入范围。您可以向左或向右拖动它,它会减少/增加“sortingSpeed”变量。但是,当我尝试启动我的程序时,我收到一个编译器错误,提示“TypeError: Cannot read property 'addEventListener' of null.”

这是我的代码:

var sliderForSortingSpeed = document.getElementById('array-speed-slider');
export let sortingSpeed = 0.1;

function Menubar({newArray, data}) {

    sliderForSortingSpeed.addEventListener("change", function() {
        sortingSpeed = sliderForSortingSpeed;
    })

    return(
        <div id="menubar-container">
            <label className="slider-box">
                <p className="slider-text">Sorting Speed</p>
                <input type="range" min={1} max={1000} className="slider" id="array-speed-slider" />
            </label>
        </div>
    )

我认为错误的发生是因为变量声明和初始化发生在加载 DOM 之前:

var sliderForSortingSpeed = document.getElementById('array-speed-slider');
.
.
.
<input type="range" min={1} max={1000} className="slider" id="array-speed-slider" />

我想我可以通过 useEffect 解决这个问题,这样“sliderForSortingSpeed”的初始化就会在 DOM 加载后发生。我认为当console.log(sliderForSortingSpeed); 保持正确打印“0.1”而不是“未定义”时它会起作用。

import React, { useEffect } from "react";'
var sliderForSortingSpeed; //Declaration here

export let sortingSpeed = 0.1;

function Menubar({newArray, data}) {

    useEffect(() => {
        sliderForSortingSpeed = document.getElementById('array-speed-slider'); // Initialization should happen after DOM loads
        // console.log(sliderForSortingSpeed);
    }, [])

    sliderForSortingSpeed.addEventListener("change", function() { // Still gets null error for addEventListener
        sortingSpeed = sliderForSortingSpeed;
    })

    return(
        <div id="menubar-container">
            <label className="slider-box">
                <p className="slider-text">Sorting Speed</p>
                <input type="range" min={1} max={1000} className="slider" id="array-speed-slider" />
            </label>
        </div>
    )
}

但是,我仍然收到相同的错误:“TypeError: Cannot read property 'addEventListener' of null.”

我哪里错了?这甚至是在 React 中加载 DOM 之后定义/初始化变量的最佳方法吗?

【问题讨论】:

  • 你为什么不使用 React onChange?尝试使用 getElementById() 之类的方法查询 dom 并不是一个好习惯

标签: javascript reactjs react-hooks


【解决方案1】:

React 使用与标准 JS + HTML 不同的操作程序。在使用 React 时,你应该很少使用像 document.getElementById 这样的函数。

获取输入组件值的正确方法是在创建组件时为onChange提供一个函数:

const { useState } = React;

// A slider that displays the value
function Slider({ props }) {
  const [value, setValue] = useState(1); // default value of 1
  return (<div>
      <input type="range" min="1" max="1000" value={value} onChange={e => setValue(e.target.value)} />
      <p>Value is {value}</p>
    </div>);
}

// Render it
ReactDOM.render(<Slider />, document.getElementById("react"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>

【讨论】:

    【解决方案2】:

    您正试图在 DOM 加载之前监听 DOM 元素。

    要在 React 功能组件中加载 DOM 后使用元素,您可以使用 useEffect()

    例如:

     useEffect(() => {
            var sliderForSortingSpeed = document.getElementById('array-speed-slider');
            console.log(sliderForSortingSpeed)
        }, [])
    
    

    正如@charlietfl 所说

    在尝试使用 getElementById() 之类的方法查询 dom 时,这不是一个好的做法

    【讨论】:

    • 我想 setInterval 也可以这样工作
    猜你喜欢
    • 2017-11-01
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    • 1970-01-01
    • 2012-01-28
    • 1970-01-01
    • 2010-10-13
    • 2016-02-09
    相关资源
    最近更新 更多