Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Reactjs 收到警告:Can';t在未安装的组件上执行React状态更新_Reactjs_React Native_React Router_React Hooks_Expo - Fatal编程技术网

Reactjs 收到警告:Can';t在未安装的组件上执行React状态更新

Reactjs 收到警告:Can';t在未安装的组件上执行React状态更新,reactjs,react-native,react-router,react-hooks,expo,Reactjs,React Native,React Router,React Hooks,Expo,每次运行此操作时,都会出现两次此错误。我进行了搜索,并试图取消对cleanup函数中的onAuthStateChanged()到useEffect()的订阅,但仍然收到相同的错误。另外,uploadAndCreate()函数工作得非常好,但是createPlan()甚至在createPlan()完成之前就被调用了,因为fileUrl的未定义 import React, { useState, useEffect } from "react"; import { Ima

每次运行此操作时,都会出现两次此错误。我进行了搜索,并试图取消对cleanup函数中的
onAuthStateChanged()
useEffect()
的订阅,但仍然收到相同的错误。另外,
uploadAndCreate()
函数工作得非常好,但是
createPlan()
甚至在
createPlan()
完成之前就被调用了,因为
fileUrl
未定义

import React, { useState, useEffect } from "react";
import {
    Image,
    StyleSheet,
    Text,
    TextInput,
    TouchableOpacity,
    View,
} from "react-native";
import firebase from "firebase/app";
import "firebase/auth";
import "firebase/storage";
import { Link, Redirect } from "react-router-native";
import { getDocumentAsync } from "expo-document-picker";
import plus from "../../assets/plus.png";
import cross from "../../assets/cross.png";

const NewPlan = (props) => {
    const [planName, setPlanName] = useState();
    const [categoryName, setCategoryName] = useState();
    const [isPlanCreated, setIsPlanCreated] = useState(false);
    const [currUserId, setCurrUserId] = useState();
    const [uploadProgress, setUploadProgress] = useState(0);
    const [blob, setBlob] = useState({});
    const [isPlanNameValid, setIsPlanNameValid] = useState(true);
    const [ref, setRef] = useState();
    const [fileUrl, setFileUrl] = useState();

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

        if (mounted) {
            firebase.auth().onAuthStateChanged((user) => {
                if (user) {
                    setCurrUserId(user.uid);
                }
            });
        }

        return () => {
            mounted = false;
        };
    }, []);

    const validate = () => {
        if (planName) {
            setIsPlanNameValid(true);
            uploadAndCreate();
        } else {
            setIsPlanNameValid(false);
        }
    };

    const uploadAndCreate = async () => {
        if (Object.keys(blob).length !== 0) {
            let task = ref.put(blob);

            await task.on(
                "state_changed",
                (snapshot) => {
                    let progress =
                        (snapshot.bytesTransferred / snapshot.totalBytes) * 100;

                    if (firebase.storage.TaskState.RUNNING)
                        setUploadProgress(progress);
                },
                (error) => {
                    console.log("Error uploading file: " + error);
                },
                () => {
                    task.snapshot.ref.getDownloadURL().then((downloadURL) => {
                        setFileUrl(downloadURL);
                    });
                }
            );
        }

        createPlan();
        setIsPlanCreated(true);
    };

    const createPlan = () => {
        let plansRef = firebase.database().ref().child("plans");
        let newPlanRef = plansRef.push();

        newPlanRef.set({
            plan_id: newPlanRef.key,
            plan_name: planName,
            created_by: currUserId,
            project_id: props.match.params.id,
            status: "active",
            category: categoryName || "uncategorized",
            file_url: fileUrl || "",
        });
    };

    const handlePlanName = (_planName) => setPlanName(_planName);

    return isPlanCreated ? (
        <Redirect to={"/project/" + props.match.params.id} />
    ) : (
        <View style={styles.container}>
            <Link
                to={"/project/" + props.match.params.id}
                style={styles.crossContainer}
            >
                <Image source={cross} style={styles.cross} />
            </Link>
            <View style={styles.topArea}>
                <Image source={plus} style={styles.plus} />
                <Text style={styles.title}>New Plan</Text>
                {!isPlanNameValid ? (
                    <Text style={styles.errorText}>
                        Please enter a valid name.
                    </Text>
                ) : null}
                <TextInput
                    placeholder="Plan Name"
                    style={styles.input}
                    placeholderTextColor="#fff"
                    onChangeText={handlePlanName}
                />
                {uploadProgress > 0 && uploadProgress < 100 ? (
                    <Text>Upload Progress: {uploadProgress.toFixed(0)}%</Text>
                ) : null}
                {uploadProgress === 100 ? <Text>Upload Complete</Text> : null}
                <TouchableOpacity
                    style={styles.button}
                    onPress={() => {
                        getDocumentAsync().then(async (response) => {
                            try {
                                let storageRef = firebase.storage().ref();
                                setRef(
                                    storageRef.child(
                                        response.uri.split("/")[14]
                                    )
                                );

                                let fetchResponse = await fetch(response.uri);
                                let blob = await fetchResponse.blob();

                                setBlob(blob);
                            } catch (error) {
                                console.log(error.message);
                            }
                        });
                    }}
                >
                    <Text style={styles.buttonText}>Upload Plan</Text>
                </TouchableOpacity>
            </View>
            <TouchableOpacity
                style={styles.bottomArea}
                onPress={() => {
                    validate();
                }}
            >
                <Text style={styles.createText}>Create</Text>
            </TouchableOpacity>
        </View>
    );
};

const styles = StyleSheet.create({
    // -- STYLES --
});

export default NewPlan;
import React,{useState,useffect}来自“React”;
进口{
形象,,
样式表,
文本,
文本输入,
可触摸不透明度,
看法
}从“反应本族语”;
从“firebase/app”导入firebase;
导入“firebase/auth”;
导入“firebase/storage”;
从“react router native”导入{Link,Redirect};
从“expo文档选择器”导入{GetDocumentSync};
从“../../assets/plus.png”导入plus;
从“../../assets/cross.png”导入交叉点;
const NewPlan=(道具)=>{
const[planName,setPlanName]=useState();
常量[categoryName,setCategoryName]=useState();
const[isPlanCreated,setIsPlanCreated]=useState(false);
const[currUserId,setCurrUserId]=useState();
const[uploadProgress,setUploadProgress]=useState(0);
const[blob,setBlob]=useState({});
常量[isPlanNameValid,setIsPlanNameValid]=useState(true);
const[ref,setRef]=useState();
const[fileUrl,setFileUrl]=useState();
useffect(()=>{
让我们假设这是真的;
如果(已安装){
firebase.auth().onAuthStateChanged((用户)=>{
如果(用户){
setCurrUserId(user.uid);
}
});
}
return()=>{
安装=错误;
};
}, []);
常量验证=()=>{
if(平面名称){
setIsPlanNameValid(true);
uploadAndCreate();
}否则{
setIsPlanNameValid(false);
}
};
const uploadAndCreate=async()=>{
if(Object.keys(blob).length!==0){
让任务=参考放置(blob);
等待任务(
“状态已更改”,
(快照)=>{
让进步=
(snapshot.bytesttransfered/snapshot.totalBytes)*100;
if(firebase.storage.TaskState.RUNNING)
设置加载进度(进度);
},
(错误)=>{
log(“上传文件时出错:+错误”);
},
() => {
task.snapshot.ref.getDownloadURL()。然后((downloadURL)=>{
setFileUrl(下载URL);
});
}
);
}
createPlan();
setIsPlanCreated(真);
};
const createPlan=()=>{
设plansRef=firebase.database().ref().child(“计划”);
设newPlanRef=plansRef.push();
新平面参考集({
计划id:newPlanRef.key,
计划名称:计划名称,
创建人:currUserId,
项目id:props.match.params.id,
状态:“活动”,
类别:categoryName | |“未分类”,
文件url:fileUrl | |“”,
});
};
const handlePlanName=(_planName)=>setPlanName(_planName);
是否创建了返回(
) : (
新计划
{!isplanname有效吗(
请输入有效的名称。
):null}
{uploadProgress>0&&uploadProgress<100(
上载进度:{uploadProgress.toFixed(0)}%
):null}
{uploadProgress==100?上载完成:null}
{
getDocumentAsync()。然后(异步(响应)=>{
试一试{
设storageRef=firebase.storage().ref();
setRef(
storageRef.child(
response.uri.split(“/”[14]
)
);
let fetchResponse=wait fetch(response.uri);
让blob=等待fetchResponse.blob();
setBlob(blob);
}捕获(错误){
console.log(错误消息);
}
});
}}
>
上传计划
{
验证();
}}
>
创造
);
};
const styles=StyleSheet.create({
//--风格--
});
导出默认的新计划;

装入的
变量没有任何作用。它唯一被选中的地方是
useffect
的开头,在那里它肯定是
true

虽然您可以在
onAuthStateChanged
回调中检查它:

        firebase.auth().onAuthStateChanged((user) => {
            if (mounted && user) {
                setCurrUserId(user.uid);
            }
        });
最好使用firebase返回的unsubscribe函数:

useEffect(() => firebase.auth().onAuthStateChanged((user) => {
    if (user) {
        setCurrUserId(user.uid);
    }
}), []);
或者,脱糖:

useEffect(() => {
    const unsubscribe = firebase.auth().onAuthStateChanged((user) => {
        if (user) {
            setCurrUserId(user.uid);
        }
    });
    return unsubscribe;
}, []);
在卸载组件时,您可能会执行多个异步操作,但实际上很难取消这些操作。您可以添加一个ref,指示组件当前是否已装入,并在调用任何setter函数之前检查:

const mountedRef = useRef(true);
useEffect(() => {
    const unsubscribe = firebase.auth().onAuthStateChanged((user) => {
        if (user) {
            setCurrUserId(user.uid);
        }
    });
    return () => {
        mountedRef.current = false;
        unsubscribe();
    }
}, []);
然后,例如,代替

setBlob(blob);


如果有可能异步运行的setter,请遵循相同的模式。

您的
装入的
变量没有任何作用。唯一的地方是ch
if (mountedRef.current) {
    setBlob(blob);
};