【发布时间】: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可能(总是?)尚未定义,并且没有什么需要重新定义的渲染,因为您根本没有渲染组件。