React setState inside componentDidUpdare 导致超出最大更新深度
React setState inside componentDidUpdare leads to Maximum update depth exceeded
我得到
Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
但据我所读,我应该能够在 componentDidMount 中调用 setState 而不会出错。
class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {
matchtedProducts: [],
products: [],
}
}
async componentDidMount() {
try {
const products = await getProducts()
this.setState({ products })
} catch(err) {
console.log(err)
}
}
componentDidUpdate() {
const productColor = this.props.size.trim().toLowerCase()
const productSize = this.props.color.trim().toLowerCase()
const matches = []
this.state.products.map(product => {
const title = product.title
const titleSpliitet = title.split(',')
let color = titleSpliitet[1].trim().toLowerCase()
let size = titleSpliitet[2].trim().toLowerCase()
if(color == productColor && size == productSize) {
matches.push(product)
}
})
this.setState({matchtedProducts: matches})
}
render() {
return (<div></div>)
}
}
我认为你必须将 prevProps
and/or prevState
作为 componentDidUpdate
的参数传递,并且仅当 prop 或 属性 的状态已经改变,
示例:
componentDidUpdate(prevProps, prevState) {
// if the property count of the state has changed
if (prevState.count !== this.state.count) {
// then do your code
}
}
文档:https://en.reactjs.org/docs/react-component.html#componentdidupdate
好像是想在props改变的时候改变state来过滤一些产品。
我删除了 componentDidUpdate
代码并在组件中添加了一个方法来进行过滤,我将从父组件调用该方法
class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {
matchtedProducts: [],
products: [],
}
}
async componentDidMount() {
try {
const products = await getProducts()
this.setState({ products })
} catch(err) {
console.log(err)
}
}
updateMatches = () => {
const productColor = this.props.size.trim().toLowerCase()
const productSize = this.props.color.trim().toLowerCase()
const matches = []
this.state.products.map(product => {
const title = product.title
const titleSpliitet = title.split(',')
let color = titleSpliitet[1].trim().toLowerCase()
let size = titleSpliitet[2].trim().toLowerCase()
if(color == productColor && size == productSize) {
matches.push(product)
}
})
this.setState({matchtedProducts: matches})
}
render() {
return (<div></div>)
}
}
并在父组件中
changeSizeAndColor = () => {
//note that I called updateMatches of MyComponent
this.setState({color : ... , size : ...} , () => this.myComponent.updateMatches());
}
render() {
return <MyComponent ref={ref => this.myComponent = ref} color={...} size={...}/>
}
发生这种情况是因为每个 setState 都会触发渲染,然后再次触发 componentDidMount,这基本上会导致无限循环。
要停止该循环,您需要设置一些条件,以防止再次渲染,例如
componentDidUpdate(previousProps, previousState) {
if (previousProps.data !== this.props.data) {
this.setState({/*....*/})
}
}
我得到了相同的 error.In 使用效果方法,我使用 axios 从后端获取数据并更新了状态。但是在更新状态之前,我没有将 json 数据转换为状态的数据类型,这就是导致此错误的原因。
错误代码:
Useeffect(() => {
fetch
.then((res) =>{
setDate(res.data.date)
})
})
正确代码:
Useeffect(() => {
fetch
.then((res) =>{
setDate(new Date(res.data.date))
})
})
我得到
Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.
但据我所读,我应该能够在 componentDidMount 中调用 setState 而不会出错。
class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {
matchtedProducts: [],
products: [],
}
}
async componentDidMount() {
try {
const products = await getProducts()
this.setState({ products })
} catch(err) {
console.log(err)
}
}
componentDidUpdate() {
const productColor = this.props.size.trim().toLowerCase()
const productSize = this.props.color.trim().toLowerCase()
const matches = []
this.state.products.map(product => {
const title = product.title
const titleSpliitet = title.split(',')
let color = titleSpliitet[1].trim().toLowerCase()
let size = titleSpliitet[2].trim().toLowerCase()
if(color == productColor && size == productSize) {
matches.push(product)
}
})
this.setState({matchtedProducts: matches})
}
render() {
return (<div></div>)
}
}
我认为你必须将 prevProps
and/or prevState
作为 componentDidUpdate
的参数传递,并且仅当 prop 或 属性 的状态已经改变,
示例:
componentDidUpdate(prevProps, prevState) {
// if the property count of the state has changed
if (prevState.count !== this.state.count) {
// then do your code
}
}
文档:https://en.reactjs.org/docs/react-component.html#componentdidupdate
好像是想在props改变的时候改变state来过滤一些产品。
我删除了 componentDidUpdate
代码并在组件中添加了一个方法来进行过滤,我将从父组件调用该方法
class MyComponent extends Component {
constructor(props) {
super(props);
this.state = {
matchtedProducts: [],
products: [],
}
}
async componentDidMount() {
try {
const products = await getProducts()
this.setState({ products })
} catch(err) {
console.log(err)
}
}
updateMatches = () => {
const productColor = this.props.size.trim().toLowerCase()
const productSize = this.props.color.trim().toLowerCase()
const matches = []
this.state.products.map(product => {
const title = product.title
const titleSpliitet = title.split(',')
let color = titleSpliitet[1].trim().toLowerCase()
let size = titleSpliitet[2].trim().toLowerCase()
if(color == productColor && size == productSize) {
matches.push(product)
}
})
this.setState({matchtedProducts: matches})
}
render() {
return (<div></div>)
}
}
并在父组件中
changeSizeAndColor = () => {
//note that I called updateMatches of MyComponent
this.setState({color : ... , size : ...} , () => this.myComponent.updateMatches());
}
render() {
return <MyComponent ref={ref => this.myComponent = ref} color={...} size={...}/>
}
发生这种情况是因为每个 setState 都会触发渲染,然后再次触发 componentDidMount,这基本上会导致无限循环。 要停止该循环,您需要设置一些条件,以防止再次渲染,例如
componentDidUpdate(previousProps, previousState) {
if (previousProps.data !== this.props.data) {
this.setState({/*....*/})
}
}
我得到了相同的 error.In 使用效果方法,我使用 axios 从后端获取数据并更新了状态。但是在更新状态之前,我没有将 json 数据转换为状态的数据类型,这就是导致此错误的原因。
错误代码:
Useeffect(() => {
fetch
.then((res) =>{
setDate(res.data.date)
})
})
正确代码:
Useeffect(() => {
fetch
.then((res) =>{
setDate(new Date(res.data.date))
})
})