在功能组件中反应类似构造函数的方法

时间:2019-04-28 18:22:00

标签: reactjs

现在有了react hook,我们可以在功能组件中拥有状态,所以我尝试重写以前使用类组件编写的小项目,在此过程中我遇到了一个可能需要解释的问题,但我想成为当然。

简要概述

因此,在我的App.js组件中,我获取数据,然后将其作为props传递到一个列表组件,该组件逐步呈现数据。首先显示4个项目,然后滚动更多内容。

我这样做的方式是,api给了我30个项目的数组,我将其全部传递给list组件,在其中我有一个底层数组,我不断从项目中提取并更新状态,它呈现。

示例代码

class List extends Component {
    constructor() {
        super();
        this.underlyingArray = [];
        this.state = {
            visibleList: []
        }
    }
    componentDidUpdate() {
        // checks if we have data 
        // populates the underlyingArray only if it's empy
    }

    render() {
        return this.state.visibleList
    }
}

在构造函数中,我将underlyingArray初始化为空,然后在有数据时填充它。


现在,当我尝试将所有内容转换为功能组件时,underlying array会在每次状态更改时不断被清除或初始化

示例代码

const List = (props) => {
    let underlyingArray = [];
    let [visibleList, setVisibleList] = useState([])

    useEffect(() => {

        // checks if we have data 
        // populates the underlyingArray only if it's empy

    }, [props.data]); // runs the above code when we receive data from the api call

    return visibleList;
}

因此,我尝试在函数顶部放置一个console.log(),并发现每当状态发生变化时,我都会看到该日志记录消息,因此我查找了一个解决方案,并找到了一些建议使用SO useRef()钩有效。

但是,如果我多次调用要在顶部执行一些内部管理工作的函数,这会引发性能问题,因为我只会运行一次,并且由于钩子使功能组件可以使用状态,因此构造函数在哪里类似的功能?

因此,除了使用constructor-like functionality之外,还有useRef()来初始化组件,因为如果提供了功能,它仍将在每个渲染器上运行。

3 个答案:

答案 0 :(得分:3)

您可以传递一个空数组作为useEffect的第二个参数:

useEffect(() => {
  // Some initialization logic here
}, []);

这样,仅在安装或卸载组件时才使用效果。

答案 1 :(得分:1)

功能组件执行每个调用中的所有代码行,因此您的第一行代码将在组件的每个“渲染/调用”中执行。

如果您的underlyingArray变量必须在所有调用之间保持其值,则必须使用useState(initialValue)钩子。 initialValue归因于首次渲染(如构造函数)之前的安装。

功能组件的执行方式类似于javascript函数,因此函数中声明的所有常量在返回后都不会保留。

useEffect不能像类组件的构造方法那样工作,因为该构造函数是在第一次渲染之前调用的,而依赖项中带有空数组的useEffect是在第一次返回之后调用的,而useEffect的return函数在“卸载”)。

您必须使用钩子重建另一个逻辑:

1-创建visibleList和underlyingArray的状态:

let [visibleList, setVisibleList] = useState([]);
let [underlyingArray, setUnderlyingArray] = useState([]);

2-使您的逻辑在使用中效果:

useEffect(()=>{
//Update underlyingArray if you have to
//Update visibleList if you have to
},[props.data]);

不要在useEffect函数的依赖项中添加空数组,因为您必须检查是否要在道具的每次更改中更新可见数组?

答案 2 :(得分:1)

您可以使用 useMemo 来演示作为功能组件的构造函数。有人建议使用 useEffect 但它会在渲染后调用。

useMemo(() => {
  console.log('This is useMemo')
}, []);