有一个唠叨的问题,并想知道是否有人可以解释一下。
我创建了一个功能,可以自动为我的反应应用程序进行路由...但我正在尝试将一个按钮附加到此功能,以确保它在按钮单击时启动和停止。但是,当我尝试下面的代码时......没有任何反应
class App extends React.Component {
constructor (props) {
super(props);
this.state = { tabControl: true };
this.handleClick = this.handleClick.bind(this);
this.tabControl = this.tabControl.bind(this);
}
tabControl(props){
RoutePaths(this.props);
}
handleClick() {
this.setState(function (prevState, props){
return { tabControl: !prevState.tabControl }
});
}
render() {
return (
<div className="clearfix" id="topContent">
<Sidebar />
<div className="white-bg" id="page-wrapper">
<Header tagline="Welcome to JuDGE" />
<button className="AutoTab" onClick={this.handleClick}>
Toggle
</button>
........
但是当我尝试第二个代码时,Tab键功能会在点击按钮时启动,但当你再次点击按钮时当然不会停止。
class App extends React.Component {
constructor (props) {
super(props);
this.state = { tabControl: true };
this.handleClick = this.handleClick.bind(this);
this.tabControl = this.tabControl.bind(this);
}
tabControl(props){
RoutePaths(this.props);
}
handleClick() {
this.setState(function (prevState, props){
return { tabControl: !prevState.tabControl }
});
}
render() {
return (
<div className="clearfix" id="topContent">
<Sidebar />
<div className="white-bg" id="page-wrapper">
<Header tagline="Welcome to JuDGE" />
<button className="AutoTab" onClick={this.tabControl}>
Toggle
</button>
答案 0 :(得分:1)
尝试使用当前状态而不是setState
中的可选回调:
handleClick() {
this.setState({ tabControl: !this.state.tabControl });
}
答案 1 :(得分:1)
我不确定我是否完全得到你想要做的事情,但在我看来你忘记了一个条件。
你说如果你调用这个方法:
tabControl(props){
RoutePaths(this.props);
}
它有效,但不会停止。
嗯,你没有条件地运行它。
在这种方法中:
handleClick() {
this.setState(function (prevState, props){
return { tabControl: !prevState.tabControl }
});
}
您正在设置tabControl
状态。我想你在运行tabControl()
之前忘了检查它。
tabControl(props){
const {tabControl} = this.state;
tabControl && RoutePaths(this.props); // invoke of tabControl is true
}
修改
在您发表评论后看到RoutePaths
的代码:
function RoutePaths(props) {
let pathUrls = ['/deploymentqueue', '/deploydb', '/currentstatus'];
let paths = pathUrls.length;
let index = 0;
let interval = 3000;
setInterval(() => {
props.history.push(pathUrls[index]);
index = (index + 1) % paths;
}, interval);
}
在我看来,你会遇到另一个问题。您需要从setInterval
返回的间隔的ID才能停止它,但您没有将其存储在任何地方。
引自docs:
...它返回一个唯一标识间隔的间隔ID, 所以你可以稍后通过调用clearInterval()...
删除它
因此,您需要将其存储在某处并使用clearInterval
致电ID
。
this.intervalId = setInterval(() => {...});
你班上的其他地方:
clearInterval(this.interval);
编辑#2
作为评论的后续内容,以下是使用react的简单用法:
class Timer extends React.Component {
constructor(props) {
super(props);
this.state = {
ticks: 0
};
}
onStart = () => {
this.intervalId = setInterval(() => {
this.setState({ ticks: this.state.ticks + 1 })
}, 500);
}
onStop = () => {
clearInterval(this.intervalId)
}
render() {
const { ticks } = this.state;
return (
<div>
<button onClick={this.onStart}>Start</button>
<button onClick={this.onStop}>Stop</button>
<div>{ticks}</div>
</div>
);
}
}
ReactDOM.render(<Timer />, document.getElementById("root"));
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
&#13;
所以你可以尝试这种方法,
RoutePaths
将返回间隔ID:
function RoutePaths(props) {
let pathUrls = ['/deploymentqueue', '/deploydb', '/currentstatus'];
let paths = pathUrls.length;
let index = 0;
let interval = 3000;
return setInterval(() => {
props.history.push(pathUrls[index]);
index = (index + 1) % paths;
}, interval);
}
和tabControl
将存储ID并有条件地调用或清除间隔:
tabControl() {
const { tabControl } = this.state;
if (tabControl && this.intervalId) { // i'm not sure this is the condition you want, but you can play with it
clearInterval(this.intervalId);
} else {
this.intervalId = RoutePaths(this.props);
}
}
我还没有对此代码进行过测试,但我认为它可以让您有一个良好的开端。
答案 2 :(得分:0)
您不需要tabControl状态来执行您要执行的操作。但是,您需要在某处调用clearInterval。更改你的句柄点击这样的东西:
handleClick() {
// change RoutePath to return the id that setInterval returns.
if (this.routePathInterval) {
clearInterval(this.routePathInterval);
this.routePathInterval = null;
} else {
this.routePathInterval = RoutePath(this.props);
}
}
&#13;
此外,当您调用clearInterval然后再次启动它时,您的索引将从零开始。如果要从您所在的索引中恢复,您可能希望将当前索引保持在状态并将其传递给RoutePath。
修改强>
第二个想法是,您不需要将索引保持在状态,因为您不希望在递增时触发重新渲染。但是,您应该将索引设为实例变量,并使RoutePath成为App组件的实例方法。
首先,在构造函数中初始化this.index = 0;
,然后:
routePaths() {
let pathUrls = ['/deploymentqueue', '/deploydb', '/currentstatus'];
let paths = pathUrls.length;
let interval = 3000;
return setInterval(() => {
this.props.history.push(pathUrls[index]);
this.index = (this.index + 1) % paths;
}, interval);
}
&#13;