useState Hook的set方法不会重新渲染用过的Hooks

时间:2020-06-09 22:00:04

标签: reactjs react-native react-hooks

当我使用“ setFavorite”更新状态时,它将重新呈现我的组件,而不是组件中使用的挂钩。 在这种情况下,更新状态时不会调用React.useLayOutEffect,但是会调用alert(“ test”)。

当我使用expo刷新时,它会重新渲染useLayoutEffect Hook,一切正常。

您对此有任何解决方案吗?

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坐下,consetetur坐立不安,sed diam nonumy eirmod tempor invidunt ut Labore et dolore magna aliquyam erat,sed diam voluptua。在Vero eos etAccusam和Justo duo dolores et ea rebum。 Stet clita kasd gubergren,没有大海,也没有Lorem ipsum dolor坐下。

1 个答案:

答案 0 :(得分:1)

useEffectuseLayoutEffect挂钩获得依赖状态的第二个参数,该参数将用于评估挂钩是否必须重新运行。

useEffect(callback, dependencies)

useLayoutEffect(callback, dependencies)

请参阅:https://reactjs.org/docs/hooks-reference.html#uselayouteffect

因此,在您的示例中,请确保favorit的依赖项列表中包含useLayoutEffect

React.useLayoutEffect(() => {
    alert('re-render with: ' + favorit);
    navigation.setOptions({
        headerRight: () => <HeaderRight />,
    });
}, [navigation, favorit]);