使用上下文和挂钩更新未安装组件的状态 - 本机反应

update state on unmonted component with context and hooks - react native

更新: 我在这个 中应用了讲师,但即使使用状态 isMounteduseEffect 清理功能我仍然无法解决这个问题。代码似乎工作正常,但我总是收到此警告。

我有一个应用程序组件,它通过条件呈现管理两个页面的导航,如果我已登录,我会输入一个,如果我没有登录,我会输入另一个。

import {context} from "./components/context"

const Stack = createNativeStackNavigator();

export default function App() {
    const [isLoggedIn, setLoggedIn] = useState(false);

    useEffect(() => {
        let isMounted = true;

        let store = async () => {
            await SecureStore.deleteItemAsync("accessToken")
            let accessToken = await SecureStore.getItemAsync("accessToken");
            if(accessToken && isMounted) {
                setLoggedIn(true)
            }
        }
        store().then()

        return () => {
            isMounted = false
        }
    }, [])

    return (
        <>
            <NavigationContainer>
                <context.Provider value={{isLoggedIn, setLoggedIn}}>
                    <Stack.Navigator >
                        <Stack.Screen name={isLoggedIn ? "HomePantry" : "Home"} component={isLoggedIn? HomePantry : Home}  />
                    </Stack.Navigator>
                </context.Provider>
            </NavigationContainer>
        </>
    );
}

我的文件context.js:

export const context = React.createContext({});

这是我的简单主页组件(在用户登录之前)。

export default function Home({navigation}) {

    return (
            <View>
                <Text> My pantry </Text>
                <UserLogin />
            </View>
    );
}

这是 UserLogin 子组件。一旦用户输入了正确的凭据,我正在使用上下文来更新 isLoggedIn 状态。问题是当应用程序组件卸载时状态会更新,这会导致无操作。

我收到此警告: “无法对未安装的组件执行 React 状态更新 - 内存泄漏?”

如果有人有任何想法,我还没有能够解决这种情况。提前致谢。

import {context} from "./context";

export default function UserLogin() {
    const contest = React.useContext(context)

    return (
        <View style={styles.inputsContainer}>
            <Formik
                initialValues={{ email: '', password: '' }}
                onSubmit={
                    async (values, actions) => {
                        if(values.email.trim() !== "" && values.password.trim() !== ""){
                            const response = await fetch('https://lam21.iot-prism-lab.cs.unibo.it/auth/login', {
                                method: 'POST',
                                headers: {
                                    'Content-Type': 'application/json'
                                },
                                body: JSON.stringify({
                                    email: values.email,
                                    password: values.password
                                })
                            });
                            let json = await response.json()
                            if(json.accessToken){
                                contest.setLoggedIn(true)
                                await SecureStore.setItemAsync("accessToken", json.accessToken);
                                actions.resetForm({})
                            } else {
                                alert("Username o password sbagliati!")
                            }
                        }}}
            >
                {({ handleChange, handleBlur, handleSubmit, values }) => (
                    <View style={styles.inputsContainer}>
                        <Text style={styles.labelText}> Email </Text>
                        <TextInput
                            required
                            onChangeText={handleChange('email')}
                            onBlur={handleBlur('email')}
                            value={values.email}
                            placeholder={"Inserisci la tua mail.."}
                            style={styles.inputText}
                        />
                        <Text style={styles.labelText}> Password </Text>
                        <TextInput
                            required
                            onChangeText={handleChange('password')}
                            onBlur={handleBlur('password')}
                            value={values.password}
                            placeholder={"Inserisci la tua password.."}
                            style={styles.inputText}
                        />
                        <View style={styles.inputButton}>
                            <Button onPress={handleSubmit} title="Submit" color="purple" style={styles.inputButton} />
                        </View>
                    </View>
                )}
            </Formik>
        </View>
    );
}

登录后的homepantry组件:

export default function HomePantry() {

    return (
        <View>
            <Text> My pantry </Text>
        </View>
    );
}

问题是当您在 promise 上设置状态时。该组件在 promise 解决之前就已经挂载了,所以您只需要检查它是否仍然挂载即可;

useEffect(() => {
        let isMounted = true;
        let store = async () => {
            let accessToken = await SecureStore.getItemAsync("accessToken");
            if(accessToken && isMounted){
                setLoggedIn(true)
            }
        }
        store().then()
        return () => {
            isMounted = false;
        };
    },[]);