javascript - 复选框和新组件,工作不规律
问题描述
您好我正在尝试使用复选框的数据构建一个新组件,为此我有以下代码:
import React from "react";
import BottomScrollListener from "react-bottom-scroll-listener";
import ThingsQuery from "./../querys/ThingsQuery";
import "./styles/Things.scss";
export default class Things extends React.Component {
constructor() {
super();
this.displayData = [this.createPag()];
}
state = {
sort: "popular",
page: 1,
featured: false,
allPages: false,
};
createPag = (onNull = () => {}) => {
return (
<ThingsQuery
page={this.state.page}
sort={this.state.sort}
featured={this.state.featured}
onNull={onNull}
/>
);
};
handleSortClick = (e) => {
const sort = e.target.innerText.trim().toLowerCase();
this.setState({ sort, page: 1, allPages: false }, () => {
this.displayData = [this.createPag()];
});
};
changePage = () => {
if (!this.state.allPages) {
const currentPage = this.state.page + 1;
this.setState({ page: currentPage });
const page = this.createPag(() => {
this.setState({ allPages: true });
});
if (!this.state.allPages) {
this.displayData.push(page);
}
}
};
handleChangeFeatured = (e) => {
const featured = e.target.checked;
console.log("onChangeFeatured");
console.log(featured);
this.setState({ page: 1, allPages: false, featured: featured }, () => {
console.log("State changed");
this.displayData = [this.createPag()];
});
};
render() {
return (
<div className="things col-xs-1 text-center">
<BottomScrollListener onBottom={this.changePage} />
<div>
<div className="custom-control custom-switch">
<input
onChange={this.handleChangeFeatured}
type="checkbox"
className="custom-control-input"
id="customSwitch1"
checked={this.state.featured}
/>
<label className="custom-control-label" for="customSwitch1">
Featured
</label>
</div>
<div className="btn-group" role="group" aria-label="Basic example">
<button
onClick={this.handleSortClick}
type="button"
className="btn btn-secondary"
>
Popular
</button>
<button
onClick={this.handleSortClick}
type="button"
className="btn btn-secondary"
>
Newest
</button>
<button
onClick={this.handleSortClick}
type="button"
className="btn btn-secondary"
>
Latest
</button>
</div>
<div className="container">
<div className="card-columns">{this.displayData}</div>
</div>
</div>
</div>
);
}
}
如您所见,我有一个复选框,它的选中值是由 state.featured 获得的。
这会正确加载如果我输入代码featured=True
,加载它,如果我输入 false 也可以。
问题是尝试更改浏览器上的值时。
当我点击开关时,这个变化,值也发生变化,并且createPag
,完全执行,但<ThingsQuery .... />
在第一次点击时不起作用,我需要将选中的值更改2次,当然,在此之后,我得到了我想要的相反数据。
我该如何解决这个问题,为什么<ThingsQuery.../>
在第一次点击时不运行?
谢谢
解决方案
存储为局部实例变量的值,即this.displayData
在更改时不会导致重新渲染。它们必须处于状态,并通过setState
更改来触发重新渲染。
因此,在您的情况下,您调用setState
change sort
and allPages
,然后在状态更改和随后的重新渲染之后,您this.displayData
在setState
回调中 change 。由于重新渲染已经完成,并且更改局部实例变量不会导致重新渲染,因此在下一次运行之前没有任何变化并且setState
使用该 new 调用重新渲染displayData
。
如果您希望更改this.displayData
导致重新渲染,它应该处于状态。任何影响渲染内容的值都应该处于状态。
推荐阅读
- matlab - 使用“subs”函数评估“dsolve”的输出在 Maltab 中提供额外的输出
- angular - 用于垫表的单个列过滤器
- ionic3 - 错误:未捕获(承诺中):错误:StaticInjectorError(AppModule)[login]:Ngx-translate
- c++ - C++ 包含文件错误
- javascript - Curiosity on react(?) or javascript syntax
- batch-file - 从文件循环读取的行在批处理程序中未正确分配
- reactjs - Cannot read property 'Vector'/'Draw' of undefined in React JS
- python - 使异步事件循环响应 Windows(和 Unix)上的 KeyboardInterrupt
- c# - AForge 在加载大尺寸 AVI 文件时显示错误:“无法打开指定的 AVI 文件”
- java - Hibernate Pagination 在使用事务时会留下一些记录