Javascript 在这个代码中setState是否一次又一次地运行?
我创建了三个react组件,我不知道为什么会收到无限网络请求和此警告:index.js:1375警告:无法在现有状态转换期间更新(例如在Javascript 在这个代码中setState是否一次又一次地运行?,javascript,reactjs,Javascript,Reactjs,我创建了三个react组件,我不知道为什么会收到无限网络请求和此警告:index.js:1375警告:无法在现有状态转换期间更新(例如在渲染中)。渲染方法应该是道具和状态的纯函数。 在MenuCategory中(见App.js:19) 应用程序内(在src/索引js:5) 此外,MenuItems.js中的网络请求在循环中被调用。我想这是由于设置状态造成的,但我不知道错误在哪里。 这是我的代码: import React from "react"; import MenuCategory fr
渲染中)。渲染方法应该是道具和状态的纯函数。
在MenuCategory中(见App.js:19)
应用程序内(在src/索引js:5)
此外,MenuItems.js中的网络请求在循环中被调用。我想这是由于设置状态造成的,但我不知道错误在哪里。
这是我的代码:
import React from "react";
import MenuCategory from "./components/MenuCategory";
import MenuItems from "./components/MenuItems";
class App extends React.Component {
constructor(props) {
super(props);
this.state = { shortName: "" };
}
handleProps = ss => {
if (this.state.shortName === "") {
this.setState({ shortName: ss });
}
// console.log(ss, ".../PP");
};
render() {
return (
<div className="App">
<MenuCategory callback={this.handleProps} />
<MenuItems shortNameProp={this.state.shortName} />
</div>
);
}
}
export default App;
从“React”导入React;
从“/components/MenuCategory”导入MenuCategory;
从“/components/MenuItems”导入菜单项;
类应用程序扩展了React.Component{
建造师(道具){
超级(道具);
this.state={shortName:”“};
}
手杖=ss=>{
如果(this.state.shortName==“”){
this.setState({shortName:ss});
}
//控制台日志(ss,“…/PP”);
};
render(){
返回(
);
}
}
导出默认应用程序;
从“React”导入React;
类MenuCategory扩展了React.Component{
建造师(道具){
超级(道具);
this.state={category:,selectedCat:};
}
异步不安全组件willmount(){
常量url=”http://stream-restaurant-menu-svc.herokuapp.com/category";
等待获取(url)
.then(data=>data.json())
.然后(元素=>{
this.setState({category:element});
});
}
menuCat=()=>{
设cat=this.state.category;
//console.log(cat,“…cat”,this.state.selectedCat,“…cat”);
如果(this.state.selectedCat!==“”){
this.props.callback(this.state.selectedCat);
}
返回cat.map(项目=>{
返回(
this.setState({selectedCat:items.short_name})
>
{items.name}
);
});
};
render(){
返回{this.state.category.length>0?this.menuCat():null};
}
}
导出默认菜单类别;
从“React”导入React;
类MenuItems扩展了React.Component{
建造师(道具){
超级(道具);
this.state={catItems:,items:};
}
renderItems=()=>{
让shortName=this.props.shortNameProp;
如果(短名称!==“”){
常量url=
"https://stream-restaurant-menu-svc.herokuapp.com/item?category=" +
短名;
获取(url)
.then(data=>data.json())
.然后(元素=>{
this.setState({items:element});
});
}
如果(this.state.items!==“”){
让selectedMenu=this.state.items;
console.log(selectedMenu);
返回selectedMenu.map(项目=>{
返回{item.name};
});
}
};
render(){
返回{this.renderItems()};
}
}
导出默认菜单项;
让我们把App
称为家长,把MenuCategory
称为孩子。
让我们将函数调用表示为'->'
符号
有这样一个无限循环:
child.render->child.menuCat->child.props.callback->parent.handleProps->parent.setState->parent.render->child.render
如果回调
周围的if
条件为真,则可以执行。为什么在两个都是本地州的地方存储相同的数据?为什么不把国家作为道具传递给孩子呢?这将有助于消除潜在价值差异的bug因为您在做异步工作,只需使用componentDidMount
而不是UNSAFE\u componentWillMount
。另外,在MenuItem
中,无限循环是cosrenderItems
调用fetch回调中的setState
。这将触发重新渲染,这将触发调用renderItems
,调用setState
,从而触发重新渲染等。。只需在上调用fetch一次,例如,componentDidMount
并将项存储在状态中。在render中,只需渲染一个加载微调器或一些加载消息,直到定义了this.state.items
import React from "react";
class MenuCategory extends React.Component {
constructor(props) {
super(props);
this.state = { category: "", selectedCat: "" };
}
async UNSAFE_componentWillMount() {
const url = "http://stream-restaurant-menu-svc.herokuapp.com/category";
await fetch(url)
.then(data => data.json())
.then(element => {
this.setState({ category: element });
});
}
menuCat = () => {
let cat = this.state.category;
// console.log(cat, "...Cat", this.state.selectedCat, "...Cat");
if (this.state.selectedCat !== "") {
this.props.callback(this.state.selectedCat);
}
return cat.map(items => {
return (
<li
key={items.short_name}
onClick={() => this.setState({ selectedCat: items.short_name })}
>
{items.name}
</li>
);
});
};
render() {
return <div>{this.state.category.length > 0 ? this.menuCat() : null}</div>;
}
}
export default MenuCategory;
import React from "react";
class MenuItems extends React.Component {
constructor(props) {
super(props);
this.state = { catItems: "", items: "" };
}
renderItems = () => {
let shortName = this.props.shortNameProp;
if (shortName !== "") {
const url =
"https://stream-restaurant-menu-svc.herokuapp.com/item?category=" +
shortName;
fetch(url)
.then(data => data.json())
.then(element => {
this.setState({ items: element });
});
}
if (this.state.items !== "") {
let selectedMenu = this.state.items;
console.log(selectedMenu);
return selectedMenu.map(item => {
return <div key={item.name}> {item.name}</div>;
});
}
};
render() {
return <div>{this.renderItems()}</div>;
}
}
export default MenuItems;