很多开发者在使用 useState
和 useEffect
时会遇到一个问题:明明在 useEffect
中更新了状态,但是界面却没有重新渲染。这是因为 useEffect
中的更新操作发生在组件渲染之后,如果更新的不是组件的状态,就不会触发组件的重新渲染。
解决方案
我们需要将需要更新的值也设置为组件的状态,并使用 useState
来管理它。这样,当我们在 useEffect
中更新该状态时,组件就会自动重新渲染,从而反映最新的数据。
代码示例
以下代码演示了如何使用 useState
和 useEffect
来根据不同的类别筛选小说列表:
import React, { useState, useEffect } from 'react';
import { ImageBackground, SafeAreaView, StyleSheet } from 'react-native';
import NovelList from './NovelList';
import NovelToggle from './NovelToggle';
import NovelModal from './NovelModal';
// ... 假设 NOVELS 数据从其他地方获取
const NOVELS = [/* ... 小说数据 */];
const Canon = () => {
const [summaryModalOpen, setSummaryModalOpen] = useState({
isOpen: false,
novelId: null,
});
const [novelListSelector, setNovelListSelector] = useState('novels');
// 使用 useState 来管理需要更新的列表
const [novelListSelection, setNovelListSelection] = useState([]);
const canonNovels = NOVELS.filter(
(novel) => novel.is_graphic_novel === false && novel.is_canon === true
);
const canonGraphicNovels = NOVELS.filter(
(novel) => novel.is_graphic_novel === true && novel.is_canon === true
);
useEffect(() => {
// 根据 novelListSelector 的值更新 novelListSelection
if (novelListSelector === 'novels') {
setNovelListSelection(canonNovels);
} else if (novelListSelector === 'graphic-novels') {
setNovelListSelection(canonGraphicNovels);
} else {
setNovelListSelection(canonNovels.concat(canonGraphicNovels));
}
// 添加 setNovelListSelection 到依赖数组
}, [canonNovels, canonGraphicNovels, novelListSelector, setNovelListSelection]);
let pageContents;
// ... 略 ...
return (
<SafeAreaView style={styles.wrapper}>
{/* ... */}
</SafeAreaView>
);
};
// ... styles 代码略 (本文来源:tell*me*the*code.com 网)...
export default Canon;
这样,我们就可以解决 useState
和 useEffect
配合使用时遇到的界面不更新问题,从而实现根据不同条件动态更新组件的功能。