【问题标题】:Unshift function creates additional buttons when clicked via Reactjs -Jquery通过 Reactjs -Jquery 单击时,Unshift 函数会创建其他按钮
【发布时间】:2019-02-08 23:24:18
【问题描述】:

通过 Reactjs -Jquery 单击时,Unshift 函数会创建额外的按钮。

我从这个古老的网站 stackoverflow 提取了这段代码。

我在一个数组中有三个用户。 这里试图让每个用户在点击他/她对应的用户链接按钮时显示他/她的弹出框。

为此,我目前不知道如何纯粹用 reactjs 来做,所以我通过添加下面的代码将它与 jquery 结合起来

if ($.inArray(pid, this.state.data) != -1)
     {
      this.state.data.splice($.inArray(pid, this.state.data), 1);
     }
this.state.data.unshift(pid);


                var s = 270 ; // start position
        var j = 260;  //next position

        $.each( this.state.data, function( index, value ) {  
           if(index < 4){
             $('[rel="'+value+'"]').css("right",s);
             $('[rel="'+value+'"]').show();
             s = s+j;            
           }
           else{
             $('[rel="'+value+'"]').hide();
           }
        });

并且在 render 方法中,按照下面的代码将 div 的 rel 设置为 person.id

rel={person.id}

这是我的成就和问题:

当我单击每个用户按钮时,一切正常,并且显示每个用户对应的弹出框,但是这一行中的 Unshif() 函数 下面的代码会导致显示一个额外的单击按钮。

this.state.data.unshift(pid);

这个额外的点击按钮,我不知道它是从哪里来的。 所以不是有三个用户按钮,而是点击后有六个。

我不知道是否它的 jquery 组合导致了 reactjs 的问题。 有人可以帮我解决这个问题吗?

import React, { Component, Fragment } from "react";
import { render } from "react-dom";
/*
const itemToPush = {
    id: Math.random().toString(36).substr(2, 16)

}
*/

class App extends Component {
  constructor() {
    super();

    this.state = {
      showBox: false,
data: [
        { id: "1", name: "user 1" },
        { id: "2", name: "user 2"},
        { id: "3", name: "user 3"}
      ],
    };

    this.showBox = this.showBox.bind(this);
    this.closeBox = this.closeBox.bind(this);
  }



  componentWillMount() {



}




showBox = (i, pid, name) => {

alert('you opened Box for User ' +pid);

// please uncomment the code below
/*
if ($.inArray(pid, this.state.data) != -1)
     {
      this.state.data.splice($.inArray(pid, this.state.data), 1);
     }
this.state.data.unshift(pid);


                var s = 270 ; // start position
        var j = 260;  //next position

        $.each( this.state.data, function( index, value ) {  
           if(index < 4){
             $('[rel="'+value+'"]').css("right",s);
             $('[rel="'+value+'"]').show();
             s = s+j;            
           }
           else{
             $('[rel="'+value+'"]').hide();
           }
        });

*/      

    //event.preventDefault();

    this.setState({ showBox: true }, () => {
     document.addEventListener('click', this.closeBox);
    });

  }

  closeBox(event) {

    if (this.dropdownBox.contains(event.target)) {
      this.setState({ showBox: false }, () => {
      document.removeEventListener('click', this.closeBox);
      });   

    }
  }
  render() {


var hidden = {
            display: this.state.shownToggle ? "none" : "block"
        }


    return (
      <div>


          <ul  style={{float: "right"}}>
            {this.state.data.map((person, i) => (

              <div className="chat-sidebar" key={i}>

                <button onClick={ () => this.showBox(i, person.id, person.name)}>
                 {person.name} Box</button>




        {this.state.showBox
            ? (



<div rel={person.id} style={{right: '270px',position: 'fixed', bottom:'-5px', width:'250px',background: 'white',borderRadius:'5px 5px 0px 0px'}}>
<div >
<div ref={(element) => {this.dropdownBox = element;}} style={{color: 'white',background: 'black'}}>Close</div>
 </div>
<div> <div style={{background: 'red',height: '100px'}}>Content will be here............<div ref={(element) => {this.dropdownBox = element;}} style={{color: 'blue'}}>Close</div></div>
</div>           
</div>
            ): (
              null
            )}



</div>

            ))}
          </ul>

      </div>
    );
  }
}

根据 Arun Krish 爵士的更新......

Arun Krish 爵士,我已经更新了下面的代码以反映您的解决方案,但仍然遇到单击后额外三个弹出按钮的相同问题。

这就是发生的事情。最初,该应用程序具有代表三个用户的三个按钮。当我点击每个按钮时,将显示用户弹出框,但每个按钮都会显示一个附加的空按钮。

请您进一步帮助我。请先生,您能否用纯 reactjs 替换该 jquery 代码。谢谢 下面是截图

从“反应”导入反应,{组件,片段}; 从“react-dom”导入{渲染}; 从'axios'导入axios; //import './style_chat.css';

const itemToPush = {
    id: Math.random().toString(36).substr(2, 16)

}


class ChatReact extends Component {
  constructor() {
    super();

    this.state = {
      showBox: false,
data: [
        { id: "1", name: "user 1" },
        { id: "2", name: "user 2"},
        { id: "3", name: "user 3"}
      ],
    };

    this.showBox = this.showBox.bind(this);
    this.closeBox = this.closeBox.bind(this);
  }
 componentWillMount() { 
}




showBox = (i, pid, name) => {
alert('you opened Box for User ..... ' +pid);

const dataSet = this.state.data;
  if ($.inArray(pid, dataSet) != -1)
   {
    dataSet.splice($.inArray(pid, this.state.data), 1);
    }
    dataSet.unshift(pid);
    var s = 270 ; // start position
    var j = 260;  //next position

    $.each( dataSet, function( index, value ) {  
       if(index < 4){
         $('[rel="'+value+'"]').css("right",s);
         $('[rel="'+value+'"]').show();

         s = s+j;   

       }
       else{
         $('[rel="'+value+'"]').hide();
       }
    });

    //event.preventDefault();

    this.setState({ showBox: true }, () => {

     document.addEventListener('click', this.closeBox);
    });

  }

  closeBox(event) {

    if (this.dropdownBox.contains(event.target)) {
      this.setState({ showBox: false }, () => {
      document.removeEventListener('click', this.closeBox);
      });   

    }
  }
  render() {


var hidden = {
            display: this.state.shownToggle ? "none" : "block"
        }


    return (
      <div>


          <ul  style={{float: "right"}}>
            {this.state.data.map((person, i) => (

              <div className="chat-sidebar" key={i}>

                <button onClick={ () => this.showBox(i, person.id, person.name)}>
                 {person.name} Box</button>




        {this.state.showBox
            ? (



<div rel={person.id} className="msg_box" style={{right: '270px',position: 'fixed', bottom:'-5px', width:'250px',background: 'white',borderRadius:'5px 5px 0px 0px'}}>
<div >
<div ref={(element) => {this.dropdownBox = element;}} style={{color: 'white',background: 'black'}}>Close</div>
 </div>
<div> <div style={{background: 'red',height: '100px'}}>Content will be here............<div ref={(element) => {this.dropdownBox = element;}} style={{color: 'blue'}}>Close</div></div>
</div>           
</div>
            ): (
              null
            )}



</div>

            ))}
          </ul>

      </div>
    );
  }
}

【问题讨论】:

  • 所以,有几件事。首先,永远不要直接修改this.state(比如使用unshift)。当你想修改 React 状态时,你应该总是使用this.setState。其次,几乎没有充分的理由混合 React 和 jQuery。 jQuery 依赖于直接的 DOM 操作(例如您的 $('[rel="'+value+'"]').show();),这可能会导致 React 出现问题。
  • 顺便说一句,可以直接修改state 的地方是在构造函数中,因为setState 可能(总是?)尚未定义,并且没有什么需要重新定义的渲染,因为您根本没有渲染组件。

标签: jquery reactjs


【解决方案1】:

您可以将状态分配给变量,从而避免直接操作状态

  const dataSet = this.state.data;
  if ($.inArray(pid, dataSet) != -1)
   {
    dataSet.splice($.inArray(pid, this.state.data), 1);
    }
    dataSet.unshift(pid);
      var s = 270 ; // start position
    var j = 260;  //next position

    $.each( dataSet, function( index, value ) {  
       if(index < 4){
         $('[rel="'+value+'"]').css("right",s);
         $('[rel="'+value+'"]').show();
         s = s+j;            
       }
       else{
         $('[rel="'+value+'"]').hide();
       }
    });
//event.preventDefault();

this.setState({ showBox: true }, () => {
 document.addEventListener('click', this.closeBox);
});

}

【讨论】:

  • Arun Krish 爵士,感谢您迄今为止所做的贡献。我已经实施了您的解决方案,但仍然遇到单击后出现三个空按钮的相同问题。我添加了显示我不知道它来自哪里的另外三个空按钮的屏幕截图。请先生,您能在我的帖子上看到根据 Arun Krish 爵士的更新部分……了解详细信息。谢谢之间
  • 感谢阿伦爵士。您的解决方案对我很有帮助
猜你喜欢
  • 2012-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-28
  • 2021-04-21
  • 2012-08-29
  • 1970-01-01
  • 2020-03-12
相关资源
最近更新 更多