useState Hook 的 set 方法不会重新渲染使用过的 Hook [英] set method for useState Hook doesn't re-render used Hooks
问题描述
当我使用setFavorite"更新我的状态时,它会重新渲染我的组件而不是我的组件中使用的钩子.在这种情况下,当我更新状态时不会调用 React.useLayOutEffect,而是调用了 alert("test").
When I update my state using "setFavorite", it re-renders my Component but not the hooks, used in my component. In this case, React.useLayOutEffect isn't called when I update my state, but the alert("test") is called.
当我使用 expo 刷新时,它会重新渲染 useLayoutEffect Hook,并且一切正常.
When I refresh using expo, it re-renders the useLayoutEffect Hook and everything works fine.
你有什么解决办法吗?
const database = SQLite.openDatabase('favoriten.db');
export default function LokalDetailsScreen(props) {
const [lokal, setLokal] = React.useState(props.route.params.lokal);
const [favorit, setFavorit] = React.useState(false);
const [navigation, setNavigation] = React.useState(props.navigation);
React.useEffect(() => {
database.transaction((transaction) =>
transaction.executeSql(
'CREATE TABLE IF NOT EXISTS favoriten (id INTEGER PRIMARY KEY NOT NULL, lokalID TEXT)'
)
);
_retrieveData(lokal.id, setFavorit);
});
alert('test');
let HeaderRight = () =>
favorit ? (
<MaterialIcons
style={styles.icon}
name={'favorite'}
size={33}
color={'red'}
onPress={() => {
_delFromDB(lokal.id, setFavorit);
}}
/>
) : (
<MaterialIcons
style={styles.icon}
name={'favorite-border'}
size={33}
color={'red'}
onPress={() => {
_saveToDB(lokal.id, setFavorit);
}}
/>
);
React.useLayoutEffect(() => {
alert('re-render with: ' + favorit);
navigation.setOptions({
headerRight: () => <HeaderRight />,
});
}, [navigation]);
return (
<ScrollView style={styles.scrollView} contentContainerStyle={styles.container}>
<View style={styles.large}>
<Image style={styles.image} source={{ uri: lokal.titelbildURL }} />
<Text>{lokal.name}</Text>
<Text>{`Favorit: ${favorit}`}</Text>
</View>
</ScrollView>
);
}
function _saveToDB(id, setFavorit) {
database.transaction((transaction) => {
transaction.executeSql('INSERT INTO favoriten (lokalID) VALUES (?)', [id], (_, result) => {
if (result.rowsAffected > 0) {
console.log('zu Favs hinzugefügt:' + ' ' + result.rowsAffected);
setFavorit(true);
}
});
});
}
function _delFromDB(id, setFavorit) {
database.transaction((transaction) =>
transaction.executeSql('DELETE FROM favoriten WHERE lokalID = ?', [id], (_, result) => {
if (result.rowsAffected > 0) {
console.log('von Favs entfernt:' + result.rowsAffected);
setFavorit(false);
} else {
console.log('nicht von Favs entfernt:' + result.rowsAffected);
setFavorit(true);
}
})
);
}
function _retrieveData(id, setFavorit) {
var res = false;
database.transaction((transaction) =>
transaction.executeSql('SELECT * FROM favoriten WHERE lokalID = ?', [id], (_, result) => {
console.log('Zeilen mit diesem Lokal: ' + result.rows.length);
if (result.rows.length > 0) {
console.log('fav auf true gesetzt');
setFavorit(true);
} else {
console.log('fav auf false gesetzt');
setFavorit(false);
}
})
);
}
一些 Lorem ipsum dolor sat amet、consetetur sadipscing elitr、sed diam nonumy eirmod tempor invidunt ut laboure et dolore magna aliquyam erat、sed diam voluptua.在 vero eos et accusam et justo duo dolores et ea rebum.Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sat amet.
Some Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
推荐答案
useEffect
和 useLayoutEffect
钩子获取依赖状态的第二个参数,用于评估是否钩子必须重新运行.
The useEffect
and useLayoutEffect
hooks get a second parameter of dependent state which will be used to evaluate if the hook has to rerun.
useEffect(callback, dependencies)
useLayoutEffect(callback, dependencies)
参见:https://reactjs.org/docs/hooks-reference.html#uselayouteffect
因此,在您的示例中,请确保 favorit
包含在 useLayoutEffect
的依赖项列表中:
So in your example make sure that favorit
is included in the list of dependencies of the useLayoutEffect
:
React.useLayoutEffect(() => {
alert('re-render with: ' + favorit);
navigation.setOptions({
headerRight: () => <HeaderRight />,
});
}, [navigation, favorit]);
这篇关于useState Hook 的 set 方法不会重新渲染使用过的 Hook的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!