繁体   English   中英

功能组件定义在类组件的 render() 方法中,状态在通过 JSX 创建时重置,但在直接调用时不会重置

[英]Functional component definition inside class component's render() method, state resets when created through JSX, but not when called directly

如果我在类组件的render()方法中定义了一个功能组件,那么每次调用类组件的render()方法时都会重置组件的状态。 如果我直接调用功能组件,状态不会重置。

看下面的例子:

import React from 'react';
import Counter from './Counter'

const MilliCounter = ({name}) => {
    return <Counter name={name} initial={1e6} />
};

class App extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            flag: false
        }
    }

    onButtonClick = (event) => {
        this.setState({flag: !this.state.flag});
    };

    render() {
        const HundoCounter = ({name}) => {
            return <Counter name={name} initial={100} />
        };

        return (<div>
            <button onClick={this.onButtonClick}>Change State</button>
            <div>{`Flag: ${this.state.flag}`}</div>
            <HundoCounter name="Component Def Inside render() - Hundo JSX"/>
            {HundoCounter({name: 'Component Def Inside render() - Hundo Function Call'})}
            <MilliCounter name="Component Def Outside render() - Milli JSX"/>
            {MilliCounter({name: 'Component Def Outside render() - Milli Function Call'})}
        </div>)
    }
}

export default App;
import * as React from 'react'

export default class Counter extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            count: props.initial
        }
    }

    onButtonClick = (event) => {
        this.setState({
            count: this.state.count + 1
        })
    };

    render() {
        return (
            <div style={{border: '1px solid black', margin: '1rem', padding: '0.67rem'}}>
                <h6>{this.props.name}</h6>
                <p>Count: {this.state.count}</p>
                <button onClick={this.onButtonClick}>Click Me</button>
            </div>
        )
    }
}

这是显示演示应用程序运行的视频。 https://i.imgur.com/WfS8DXJ.mp4

如您所见,当单击按钮时,它会将标志更改为 true,从而强制重新渲染。 在此期间,JSX 定义的功能组件HundoCounter的状态被重置,但不是直接调用的。

状态将重置对我来说很有意义,因为每次调用render()时它都会创建HundoCounter的新定义。 为什么直接作为函数调用的HundoCounter的状态没有被重置?

我相信原因是因为您正在重新渲染父组件,然后当由于父组件重新渲染而重新渲染子组件时,它会重置 initial={100} 以将其设置回 100。

这是预期的行为

至于为什么第二个没有重置我不知道,但它没有重置似乎很奇怪,因为它的值也应该重置

好吧,这似乎很奇怪。 我认为这与 React 的reconciliation and diff算法有关。 当我将 key 属性添加到 Counter 组件时,它的行为符合我们的预期。

 const HundoCounter = ({ name }) => {
  console.log("hundo function")
  return <Counter key={Math.random()} name={name} initial={100} />
};

我认为 render() 方法被调用并且 diff 算法在先前的结果和新结果上递归,并且以某种方式函数围绕组件并且表现得就像它是同一个组件。 顺便说一句,我喜欢这个实验:)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM