我有一个“夜生活协调”应用程序(来自“免费代码营”课程),该应用程序允许用户在当天晚上按城市和RSVP搜索到酒吧。该应用程序保留了谁拥有RSVP以及谁将要去的列表。它是使用React和Bootstrap v4(以及后端的Node)构建的。
我在每个栏位置下都有文本,单击该文本可以使用户进行RSVP或取消RSVP。还有一个按钮,显示有多少人接受过RSVP,如果单击该按钮,将显示有RSVP接受者列表的Bootstrap弹出窗口。
如果用户有RSVP(或无RSVP),我希望列表更新。 (当前,按钮上的 number 会更新,但不会更新列表。)
以下两个图像显示了问题:
当用户RSVPS或取消RSVP时,按钮上的数字会正确更新,但列表不会
这是我的代码。
列表是在render方法中第二个锚标记的data-content
属性中生成的。
有人可以帮忙吗?
另一个提示是,在我的React开发人员工具Chrome扩展程序中,它显示了data-content
属性在RSVP和unRSVP上已正确更新。也许Bootstrap会在初始渲染时将data-content
属性的内容保存在其JS文件中,而不进行更新吗?
const React = require('react');
class Bar extends React.Component {
constructor(props) {
super(props);
this.state = {
countMeIn: false, // coming from Mongo
numberGoing: this.props.user_namesArr.length,
user_id: this.props.twitter_id,
user_name: this.props.user_name,
yelp_id: this.props.yelp_id,
user_namesArr: this.props.user_namesArr
};
}
componentDidMount() { // need the same for DidMount and DidUpdate, in case user is signed in upon load (from previous session), or signs in after load
if (this.state.user_namesArr.includes(this.props.user_name) && !this.state.countMeIn) {
this.setState({
countMeIn: true
});
}
}
componentDidUpdate(prevProps, prevState) { // Need both in case user logs in after initial page load
console.log(this.state.user_namesArr);
if (this.state.user_namesArr.includes(this.props.user_name) && !prevState.countMeIn) {
this.setState({
countMeIn: true
});
}
$('[data-toggle="popover"]').popover();
}
rsvp() {
let url = '/rsvp/?&yelp_id=' + this.props.yelp_id + '&user_id=' + this.props.twitter_id + '&user_name=' + this.props.user_name;
fetch(url, { method: "POST" })
.then((res) => res.json())
.then((json) => {
let newArr = this.state.user_namesArr;
newArr.push(this.props.user_name);
this.setState({
numberGoing: this.state.numberGoing + 1,
countMeIn: true,
user_namesArr: newArr,
});
})
}
unrsvp() {
let url = '/unrsvp/?&yelp_id=' + this.props.yelp_id + '&user_id=' + this.props.twitter_id + '&user_name=' + this.props.user_name;
fetch(url, { method: "POST" })
.then((res) => res.json())
.then((json) => {
let ind = this.state.user_namesArr.indexOf(this.props.user_name);
let newArr = this.state.user_namesArr;
newArr.splice(ind, 1);
this.setState({
numberGoing: this.state.numberGoing - 1,
countMeIn: false,
user_namesArr: newArr,
});
})
}
render() {
return (
<div className="col-lg-4 onecomponent">
<a href={ this.props.bar_yelp_url } target="_blank">
<div className="barname text-center">
{ this.props.name }
</div>
<div className="priceline">
<img className="stars" src={ this.state.starsUrl } /> { this.props.review_count } reviews <span className="price">{ this.props.price }</span>
</div>
<div className="image">
<img class="mainimg" src={ this.props.image_url } />
</div>
<div className="address text-center">
{ this.props.loc[0] }., { this.props.loc[1] }
</div>
</a>
<hr/>
<div className="text-center">
<a tabindex="0" role="button" className="btn btn-success" data-toggle={ this.state.user_namesArr.length > 0 ? "popover" : "" } data-trigger="focus" title="Who's In?" data-content={ this.state.user_namesArr }>
{ this.state.numberGoing } going
</a>
{
this.props.loggedIn ?
this.state.countMeIn ?
<span className="going" onClick={ () => this.unrsvp() }>You're going!</span> : // if logged in and already RSVP'd
<span className="rsvpdetails" onClick={ () => this.rsvp() }>Count me in!</span> : // if logged in but not yet RSVP'd
<span> Please log in </span> // if not logged in
}
</div>
</div>
)
}
}
module.exports = Bar;
答案 0 :(得分:0)
也许使用ref
会有所帮助...但是为什么不使用reactstrap
,更重要的是为什么不使用react-popper
...?众所周知(https://github.com/FezVrasta/popper.js/#react-vuejs-angular-angularjs-emberjs-etc-integration),许多库无法与React或任何其他(虚拟)DOM管理器配合使用。
您真的需要jQuery吗?
使用react门户,您可以删除所有这些依赖项。
答案 1 :(得分:0)
它与Reactstrap一起使用。我只是将reactstrap
添加到我的package.json文件中,并使用了Reactstrap代码。
const React = require('react');
import { Button, Popover, PopoverHeader, PopoverBody } from 'reactstrap';
class Bar extends React.Component {
constructor(props) {
super(props);
this.state = {
countMeIn: false, // coming from Mongo
numberGoing: this.props.user_namesArr.length,
user_id: this.props.twitter_id,
user_name: this.props.user_name,
yelp_id: this.props.yelp_id,
user_namesArr: this.props.user_namesArr,
popover: false
};
this.toggle = this.toggle.bind(this);
}
componentDidMount() { // need the same for DidMount and DidUpdate, in case user is signed in upon load (from previous session), or signs in after load
if (this.state.user_namesArr.includes(this.props.user_name) && !this.state.countMeIn) {
this.setState({
countMeIn: true
});
}
}
componentDidUpdate(prevProps, prevState) {
if (this.state.user_namesArr.includes(this.props.user_name) && !prevState.countMeIn) {
this.setState({
countMeIn: true
});
}
}
rsvp() {
let url = '/rsvp/?&yelp_id=' + this.props.yelp_id + '&user_id=' + this.props.twitter_id + '&user_name=' + this.props.user_name;
fetch(url, { method: "POST" })
.then((res) => res.json())
.then((json) => {
let newArr = this.state.user_namesArr;
newArr.push(this.props.user_name);
this.setState({
user_namesArr: newArr,
numberGoing: this.state.numberGoing + 1,
countMeIn: true
});
})
}
unrsvp() {
let url = '/unrsvp/?&yelp_id=' + this.props.yelp_id + '&user_id=' + this.props.twitter_id + '&user_name=' + this.props.user_name;
fetch(url, { method: "POST" })
.then((res) => res.json())
.then((json) => {
let ind = this.state.user_namesArr.indexOf(this.props.user_name);
let newArr = this.state.user_namesArr;
newArr.splice(ind, 1);
this.setState({
user_namesArr: newArr,
numberGoing: this.state.numberGoing - 1,
countMeIn: false
});
})
}
toggle() {
this.setState({
popover: !this.state.popover
});
}
render() {
return (
<div className="col-lg-4 onecomponent">
<a href={ this.props.bar_yelp_url } target="_blank">
<div className="barname text-center">
{ this.props.name }
</div>
<div className="priceline">
<img className="stars" src={ this.state.starsUrl } /> { this.props.review_count } reviews <span className="price">{ this.props.price }</span>
</div>
<div className="image">
<img class="mainimg" src={ this.props.image_url } />
</div>
<div className="address text-center">
{ this.props.loc[0] }., { this.props.loc[1] }
</div>
</a>
<hr/>
<div className="text-center">
{ /* For this to work, id must have leading letters, otherwise throws massive errors. See here: https://stackoverflow.com/questions/23898873/failed-to-execute-queryselectorall-on-document-how-to-fix */ }
<Button id={ "abc" + this.props.yelp_id } className="btn btn-success" onClick={ this.toggle }>{ this.state.numberGoing } going</Button>
<Popover placement="right" isOpen={ this.state.popover } target={ "abc" + this.props.yelp_id } toggle={ this.toggle }>
<PopoverHeader>Who's In?</PopoverHeader>
<PopoverBody>{ this.state.user_namesArr }</PopoverBody>
</Popover>
{
this.props.loggedIn ?
this.state.countMeIn ?
<span className="going" onClick={ () => this.unrsvp() }>You're going!</span> : // if logged in and already RSVP'd
<span className="rsvpdetails" onClick={ () => this.rsvp() }>Count me in!</span> : // if logged in but not yet RSVP'd
<span> Please log in </span> // if not logged in
}
</div>
</div>
)
}
}
module.exports = Bar;