Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript addEventListener在React中为空_Javascript_Reactjs - Fatal编程技术网

Javascript addEventListener在React中为空

Javascript addEventListener在React中为空,javascript,reactjs,Javascript,Reactjs,我正在使用React创建搜索功能。我以前使用过这种方法,但没有使用React,而且效果很好。现在,它在控制台中出现了一个错误,称为“UncaughtTypeError:无法读取null的属性'addEventListener'。这和它在英国制造有什么关系吗?我该如何解决这个问题 <body> <div id="searching"></div> <script type="text/babel"> class SearchBox exten

我正在使用React创建搜索功能。我以前使用过这种方法,但没有使用React,而且效果很好。现在,它在控制台中出现了一个错误,称为“UncaughtTypeError:无法读取null的属性'addEventListener'。这和它在英国制造有什么关系吗?我该如何解决这个问题

<body>
<div id="searching"></div>
<script type="text/babel">
    class SearchBox extends React.Component { render(){ return(
    <form>
        <input type="text" className="searchbox" />
    </form>) } } ReactDOM.render(
    <SearchBox />, document.getElementById("searching"));
</script>

类SearchBox扩展React.Component{render(){return(
)}}ReactDOM.render(
,document.getElementById(“搜索”);

JS

const端点=”https://gist.githubusercontent.com/Miserlou/c5cd8364bf9b2420bb29/raw/2bf258763cdddd704f8ffd3ea9a3e81d25e2c6f6/cities.json';
常量存储库=[];
获取(端点)
.then(blob=>blob.json())
.then(data=>repositories.push(…data));
函数FindMatch(wordToMatch,存储库){
返回存储库。过滤器(位置=>{
const regex=new RegExp(wordToMatch,“gi”);
return place.city.match(regex)| | place.state.match(regex);
});
};
函数displayMatches(){
const matchArray=findMatches(this.value,repositories);
常量html=matchArray.map(位置=>{
const regex=new RegExp(this.value,“gi”);
const cityName=place.city.replace(regex,`${this.value}`);
const stateName=place.state.replace(regex,`${this.value}`);
返回`
  • ${cityName},${stateName} ${numberWithCommas(place.population)}
  • `; }).加入(“”); log(匹配数组); suggestions.innerHTML=html; }; const searchInput=document.querySelector(“.searchbox”); const suggestions=document.querySelector(“.suggestions”); searchInput.addEventListener(“更改”,显示匹配项); searchInput.addEventListener(“键控”,显示匹配项);
    一般来说,将ReactJS与非ReactJS混合使用是个坏主意。React有一种非常特殊的处理事件的方法,直接调用
    addEventListener()
    时效果不佳。调用
    addEventListener()
    时,有时很可能会正常工作,但您确实不应该依赖于此

    不应将两者混合使用的原因是React可以在任何时候自由地重建DOM:任何时候出现状态更改,React都可以自行拆除DOM元素并创建新的元素,而不是您的元素。你既不知道也不关心元素何时被渲染,这就是React的一部分美

    那么,你如何处理事件呢?在创建元素时,您必须使用诸如
    onChange
    onKeyUp
    之类的属性,以一种老派的方式将它们连接起来。(在引擎盖下,React实际上会在正确的时间使用
    addEventListener
    ,但您从未真正注意到这种情况发生。)

    那么,您的代码的修订版本的结构可能如下所示:

    class SearchBox extends React.Component {
    
        constructor(props) {
            super(props);
    
            // This binding is necessary to make `this` work in the callback
            this.onKeyUp = this.onKeyUp.bind(this);
            this.onChange = this.onChange.bind(this);
        }
    
        onChange(event) {
            ...
        }
    
        onKeyUp(event) {
            ...
        }
    
        render() {
            return(
                <form>
                    <input type="text" className="searchbox" onChange={this.onChange} onKeyUp={this.onKeyUp} />
                </form>
            );
        }
    }
    
    ReactDOM.render(
        <SearchBox />,
        document.getElementById("searching")
    );
    
    类搜索框扩展了React.Component{
    建造师(道具){
    超级(道具);
    //此绑定是使`This`在回调中工作所必需的
    this.onKeyUp=this.onKeyUp.bind(this);
    this.onChange=this.onChange.bind(this);
    }
    onChange(事件){
    ...
    }
    onKeyUp(事件){
    ...
    }
    render(){
    返回(
    );
    }
    }
    ReactDOM.render(
    ,
    document.getElementById(“搜索”)
    );
    

    正如您所看到的,代码的整个结构是不同的。React不仅仅是一种轻松发布HTML元素的方式:它是一个完整的基于组件的微框架,您可以围绕它设计整个UI。

    我不同意肖恩的观点。使用本机函数很好,事实上,有时您必须这样做

    出现此错误的原因是脚本试图将侦听器添加到不存在的DOM节点:当侦听器脚本执行时,输入元素尚未刷新到DOM。这就是为什么当您需要以这种方式获取转义图案填充时,您应该在componentdidmount中从组件本身内部执行此操作,并且仅当子节点需要侦听完全未连接的父DOM节点时(例如,该节点可能位于组件所属的其他React子树之外)。这保证您试图查找的节点已经存在


    这就是说,通过这种方式使用本机函数,在95%的常见用例中应该也可以避免一个逃生舱。您应该使用更惯用的方法,将状态提升到更高级别的组件,或者如果确实需要,使用ref。

    取决于上述答案和其他地方的参考。我尝试了下面的方法,并进行了锻炼

    class Searchbox extends React.Component {
        state = {};
    
        componentDidMount = () => {  //Used for when component mounts for first time
           myfunction();
        }
    
        componentDidUpdate = () => {  //Used for every time component updates
           myfunction();
        }
    
        myfunction = () => {
           // This is function which contains addEventListeners
           // or statements like - document.getElementId("myDiv");
        }
    
        render() {
           return (
               <div id="myDiv">
                   ...
                   // body of code to render
               </div>
           );
        }
    }
    
    export default Searchbox;
    
    类搜索框扩展了React.Component{
    状态={};
    componentDidMount=()=>{//用于组件首次装载时
    myfunction();
    }
    componentDidUpdate=()=>{//用于每次组件更新
    myfunction();
    }
    myfunction=()=>{
    //这是包含addEventListeners的函数
    //或者像-document.getElementId(“myDiv”)这样的语句;
    }
    render(){
    返回(
    ...
    //要渲染的代码体
    );
    }
    }
    导出默认搜索框;
    
    我同意@Sean的观点。本机java和ReactJS有不同的生命周期来处理事件。 我添加了一些使用钩子的人。您可以使用useffect和useRef添加自定义钩子

  • 将事件处理程序创建为Ref,并在使用 使用效果
  • 使用useEffect中的目标元素和侦听器绑定事件
  • 下面是创建useEventListener自定义挂钩的示例代码。 我从中得到了这个示例代码


    如果使用React,则不应使用addEventListener。在这里读一下。此外,在这种情况下,您应该使用
    onInput
    ^他所说的内容。这些元素似乎在JS运行时不存在,可能是因为它们还没有被渲染,所以我会使用它们?我不确定
    class Searchbox extends React.Component {
        state = {};
    
        componentDidMount = () => {  //Used for when component mounts for first time
           myfunction();
        }
    
        componentDidUpdate = () => {  //Used for every time component updates
           myfunction();
        }
    
        myfunction = () => {
           // This is function which contains addEventListeners
           // or statements like - document.getElementId("myDiv");
        }
    
        render() {
           return (
               <div id="myDiv">
                   ...
                   // body of code to render
               </div>
           );
        }
    }
    
    export default Searchbox;
    
    function useEventListener(eventName, handler, element = window){
      // Create a ref that stores handler
      const savedHandler = useRef();
    
      // Update ref.current value if handler changes.
      // This allows our effect below to always get latest handler ...
      // ... without us needing to pass it in effect deps array ...
      // ... and potentially cause effect to re-run every render.
      useEffect(() => {
        savedHandler.current = handler;
      }, [handler]);
    
      useEffect(
        () => {
          // Make sure element supports addEventListener
          // On 
          const isSupported = element && element.addEventListener;
          if (!isSupported) return;
    
          // Create event listener that calls handler function stored in ref
          const eventListener = event => savedHandler.current(event);
    
          // Add event listener
          element.addEventListener(eventName, eventListener);
    
          // Remove event listener on cleanup
          return () => {
            element.removeEventListener(eventName, eventListener);
          };
        },
        [eventName, element] // Re-run if eventName or element changes
      );
    };
    export default useEventListener;