我正在使用 expo 和 React Native 构建一个应用程序。在我的项目中,我有一个包含三个 stackScreen 的 stackNavigator,我还有一个具有静态异步功能的 DatabaseManager 类。在我的组件中,我使用 useState 和 useEffect 加载我的数据并显示它们。 当我从第一个屏幕移动到第二个屏幕时,出现错误:
警告:无法在渲染不同组件 (%s
) 时更新组件 (%s
)。要在 %s
中找到错误的 setState() 调用,请按照 https://reactjs.org/link/setstate-in-render%s、StackNavigator、Screen、Screen 中所述的堆栈跟踪进行操作。
这个警告是,我想我有时需要在屏幕上点击 2 次才能在屏幕之间导航的原因。
这是我的代码的一部分:
export default class DatabaseManager {
...
static async getSplits(){
if (!this.db)
await this.openDatabase();
const query = "select distinct day from exercises";
const resultQuery = await this.executeSql(query, []);
const result = [];
var rows = resultQuery.rows;
for (let i = 0; i < rows.length; i++) {
var item = rows.item(i);
result.push({split: item.DAY});
}
return result;
}
static async getExercises( split){
if (!this.db)
await this.openDatabase();
const query = "select distinct name from exercises where day = ? order by number";
const resultQuery = await this.executeSql(query, [split]);
const result = [];
var rows = resultQuery.rows;
for (let i = 0; i < rows.length; i++) {
var item = rows.item(i);
result.push({name: item.NAME});
}
return result
}
}
App.js
...
function HomeStackScreen() {
return (
<HomeStack.Navigator initialRouteName='Home' >
<HomeStack.Screen name="Home" component={Home} options={{title:'Splits'} }/>
<HomeStack.Screen name="Screen" component={Screen} />
</HomeStack.Navigator>
);
}
...
export default function Home ({navigation}){
const [splits, setSplits] = useState([{ split:''}]);
const handlePress = async (split) => {
navigation.navigate('Screen', {split: split});
};
useEffect(() => {
const dataFetch = async () => {
const data = await DatabaseManager.getSplits();
setSplits(data);
}
dataFetch();
}, [])
return (
<View style={styleHome.container}>
<ScrollView style={styleHome.scrollViewContainer}>
{splits.map((split, index) => (
<View style={styleHome.touchableContainer} key={index}>
<Pressable
key={split.split}
style={styleHome.touchable}
activeOpacity={1}
onPress={() => handlePress(split.split)}
>
<Text style={styleHome.textTouchable}>{split.split}</Text>
</Pressable>
</View>
))}
</ScrollView>
</View>
);
第二个画面与此类似
我尝试使用useFocusEffect、enableFreeze、useFocus。我还尝试在导航到新屏幕之前放置一个加载屏幕,但没有解决问题。通过使用一些 console.log,我发现我的代码似乎是正确的,Home 组件在导航到另一个组件后不会重新呈现。
我找到了解决方案:我只是在第二个屏幕上有一个错误的 navigation.setOptions() ... 我把它包裹在 useEffect() 中,它工作正常。
我在那里找到了解决方案:https://github.com/react-navigation/react-navigation/issues/9478#issuecomment-813031134