Javascript ReactJS-无限循环调用包装方法
我有无限循环的常见问题,我不知道为什么 Im使用reactJS 16.5.2 循环通常发生在您在不允许的位置写入SetState时(例如在render方法中) 我遵循这个指南: 关注这个问题 我制作了几个HOC(Decorators/Wrapper)组件,将通用方法集中在一个点上,使用道具将它们传播给每个孩子 它通常工作得很好 我试图简化下面的组件结构 问题在于形式及其子对象。 其中一个输入有一个下拉列表,必须用上包装器的方法填充该下拉列表。我将调用放入componentDidMount(如上面的链接所示)。不幸的是,包装器setState似乎触发了表单组件的完整描述和重新构建。从包装到表单,我在每个构造函数中都放了一个console.log。只有表单及其所有输入被重新创建(而不是更新) 由于ComponentDidMount每次都会被触发,因此这种重新创建会生成一个无限循环 我不知道怎么解决这个问题。我检查了每个“键”属性,所有组件都有其唯一的键。我在问你为什么要重新创建而不是更新 是由于父渲染中的表单构建方法造成的吗?如果是这样的话,哪种设计模式适合构建具有异步数据填充的表单Javascript ReactJS-无限循环调用包装方法,javascript,reactjs,Javascript,Reactjs,我有无限循环的常见问题,我不知道为什么 Im使用reactJS 16.5.2 循环通常发生在您在不允许的位置写入SetState时(例如在render方法中) 我遵循这个指南: 关注这个问题 我制作了几个HOC(Decorators/Wrapper)组件,将通用方法集中在一个点上,使用道具将它们传播给每个孩子 它通常工作得很好 我试图简化下面的组件结构 问题在于形式及其子对象。 其中一个输入有一个下拉列表,必须用上包装器的方法填充该下拉列表。我将调用放入componentDidMount(如上面
简化您的生活,只需创建一个功能相同的
容器组件,而不是创建一堆包装器。例如,您可以创建一个关心数据和状态的容器
,然后与可重用子组件共享该容器及其方法(如下所示,两者的功能相同)
这与从API获取数据的方式完全相同。您将在componentDidMount
中检索数据,将其设置为状态
,然后将状态
传递给可重用组件
您可以使用可重用组件获得超粒度。例如,一个可重复使用的按钮,其唯一目的是提交表单。或者一个只捕获1到100之间的数字的可重用输入,以此类推
如果您的组件是嵌套的,那么考虑使用.< /P>
工作示例:
容器/Form.js(容器组件)
import React,{Component}来自“React”;
从“./组件/字段”导入字段;
导出默认类表单扩展组件{
状态={
按钮区:[
{id:“苹果”,数量:1},
{id:“草莓”,数量:1},
{id:“葡萄”,数量:1},
{id:“杏子”,数量:1}
]
};
把手按钮点击=id=>{
this.setState(prevState=>({
buttonFields:prevState.buttonFields.map(
项目=>
id==item.id?{id,数量:item.quantity+1}:{…item}
)
}));
};
渲染=()=>(
);
}
组件/Fields.js(可重用组件)
从“React”导入React;
导出默认值({buttonFields,onButtonClick,title})=>(
{title}
{buttonFields.map({id,quantity})=>(
onButtonClick(id)}
>
{id}({quantity})
))}
);
容器/Wrapper.js(不必要的包装)
import React,{Component}来自“React”;
导出默认WrappedComponent=>{
类形式扩展组件{
状态={
按钮区:[
{id:“苹果”,数量:1},
{id:“草莓”,数量:1},
{id:“葡萄”,数量:1},
{id:“杏子”,数量:1}
]
};
把手按钮点击=id=>{
this.setState(prevState=>({
buttonFields:prevState.buttonFields.map(
项目=>
id==item.id?{id,数量:item.quantity+1}:{…item}
)
}));
};
渲染=()=>(
);
}
申报表;
};
简化您的生活,而不是创建一堆包装,只需创建一个功能相同的容器组件即可。例如,您可以创建一个关心数据和状态的容器
,然后与可重用子组件共享该容器及其方法(如下所示,两者的功能相同)
这与从API获取数据的方式完全相同。您将在componentDidMount
中检索数据,将其设置为状态
,然后将状态
传递给可重用组件
您可以使用可重用组件获得超粒度。例如,一个可重复使用的按钮,其唯一目的是提交表单。或者一个只捕获1到100之间的数字的可重用输入,以此类推
如果您的组件是嵌套的,那么考虑使用.< /P>
工作示例:
容器/Form.js(容器组件)
import React,{Component}来自“React”;
从“./组件/字段”导入字段;
导出默认类表单扩展组件{
状态={
按钮区:[
{id:“苹果”,数量:1},
{id:“草莓”,数量:1},
{id:“葡萄”,数量:1},
{id:“杏子”,数量:1}
]
};
把手按钮点击=id=>{
this.setState(prevState=>({
buttonFields:prevState.buttonFields.map(
项目=>
id==item.id?{id,数量:item.quantity+1}:{…item}
)
}));
};
渲染=()=>(
);
}
组件/Fields.js(可重用组件)
从“React”导入React;
导出默认值({buttonFields,onButtonClick,title})=>(
{title}
{buttonFields.map({id,quantity})=>(
onButtonClick(id)}
>
{id}({quantity})
))}
);
容器/Wrapper.js(不必要
import React, { Component } from "react";
import Fields from "../components/Fields";
export default class Form extends Component {
state = {
buttonFields: [
{ id: "Apples", quantity: 1 },
{ id: "Strawberries", quantity: 1 },
{ id: "Grapes", quantity: 1 },
{ id: "Apricots", quantity: 1 }
]
};
handleButtonClick = id => {
this.setState(prevState => ({
buttonFields: prevState.buttonFields.map(
item =>
id === item.id ? { id, quantity: item.quantity + 1 } : { ...item }
)
}));
};
render = () => (
<Fields
{...this.state}
onButtonClick={this.handleButtonClick}
title="Container Component"
/>
);
}
import React from "react";
export default ({ buttonFields, onButtonClick, title }) => (
<div className="container">
<h1 style={{ textAlign: "center" }}>{title}</h1>
{buttonFields.map(({ id, quantity }) => (
<button
style={{ marginRight: 10 }}
className="uk-button uk-button-primary"
key={id}
onClick={() => onButtonClick(id)}
>
{id} ({quantity})
</button>
))}
</div>
);
import React, { Component } from "react";
export default WrappedComponent => {
class Form extends Component {
state = {
buttonFields: [
{ id: "Apples", quantity: 1 },
{ id: "Strawberries", quantity: 1 },
{ id: "Grapes", quantity: 1 },
{ id: "Apricots", quantity: 1 }
]
};
handleButtonClick = id => {
this.setState(prevState => ({
buttonFields: prevState.buttonFields.map(
item =>
id === item.id ? { id, quantity: item.quantity + 1 } : { ...item }
)
}));
};
render = () => (
<WrappedComponent
{...this.state}
onButtonClick={this.handleButtonClick}
title="Wrapper"
/>
);
}
return Form;
};
renderForm()
{
var WrappedFormComponent = FormHOC(SomeFormComponent();
return <WrappedFormComponent {...this.props} [...] />
}
const WrappedFormComponent = FormHOC(SomeFormComponent();
export default class FinalComponent extends React.Component