Javascript 当任何函数正在运行时,useEffect正在运行
首先,我对这个问题做了很多研究,但没有找到解决办法。如果你能帮忙,我将不胜感激 功能部件 我在下面简要地添加代码。这不是完整的代码 状态和道具Javascript 当任何函数正在运行时,useEffect正在运行,javascript,reactjs,graphql,apollo,apollo-client,Javascript,Reactjs,Graphql,Apollo,Apollo Client,首先,我对这个问题做了很多研究,但没有找到解决办法。如果你能帮忙,我将不胜感激 功能部件 我在下面简要地添加代码。这不是完整的代码 状态和道具 // blog id const { id } = props.match.params; // state const initialState = { title: "", category: "", admin_id: "", status
// blog id
const { id } = props.match.params;
// state
const initialState = {
title: "",
category: "",
admin_id: "",
status: false
};
const [form, setState] = useState(initialState);
const [adminList, setAdminList] = useState([]);
const [articleText, setArticleText] = useState([]);
const [me, setMe] = useState([]);
const [locked, setLocked] = useState(true);
const timerRef = useRef(null);
// queries and mutations
const { loading, error, data } = useQuery(GET_BLOG, {
variables: { id }
});
const { data: data_admin, loading: loading_admin } = useQuery(GET_ADMINS);
const [editBlog, { loading: loadingUpdate }] = useMutation(
UPDATE_BLOG
);
const [lockedBlog] = useMutation(LOCKED_BLOG);
多用途效应与功能
useEffect(() => {
if (!loading && data) {
setState({
title: data.blog.title,
category: data.blog.category,
admin_id: data.blog.admin.id,
status: data.blog.status
});
setArticleText({
text: data.blog.text
});
}
console.log(data);
}, [loading, data]);
useEffect(() => {
if (!loading_admin && data_admin) {
const me = data_admin.admins.filter(
x => x.id === props.session.activeAdmin.id
);
setAdminList(data_admin);
setMe(me[0]);
}
}, [data_admin, loading_admin]);
useEffect(() => {
const { id } = props.match.params;
lockedBlog({
variables: {
id,
locked: locked
}
}).then(async ({ data }) => {
console.log(data);
});
return () => {
lockedBlog({
variables: {
id,
locked: false
}
}).then(async ({ data }) => {
console.log(data);
});
};
}, [locked]);
// if loading data
if (loading || loading_admin)
return (
<div>
<CircularProgress className="loadingbutton" />
</div>
);
if (error) return <div>Error.</div>;
// update onChange form
const updateField = e => {
setState({
...form,
[e.target.name]: e.target.value
});
};
// editor update
const onChangeEditor = text => {
const currentText = articleText.text;
const newText = JSON.stringify(text);
if (currentText !== newText) {
// Content has changed
if (timerRef.current) {
clearTimeout(timerRef.current);
}
setArticleText({ text: newText });
if (!formValidate()) {
timerRef.current = setTimeout(() => {
onSubmitAuto();
}, 10000);
}
}
};
// auto save
const onSubmitAuto = () => {
if (timerRef.current) {
clearTimeout(timerRef.current);
}
editBlog({
variables: {
id,
admin_id,
title,
text: articleText.text,
category,
status
}
}).then(async ({ data }) => {
console.log(data);
});
};
// validate
const formValidate = () => {
const { title, category } = form;
return !title || !articleText.text || !category;
};
// clear state
const resetState = () => {
setState({ ...initialState });
};
return (
// jsx
)
useffect(()=>{
如果(!正在加载&数据){
设定状态({
标题:data.blog.title,
类别:data.blog.category,
管理员id:data.blog.admin.id,
状态:data.blog.status
});
setArticleText({
text:data.blog.text
});
}
控制台日志(数据);
},[加载,数据];
useffect(()=>{
如果(!加载管理和数据管理){
const me=data\u admin.admins.filter(
x=>x.id==props.session.activeAdmin.id
);
setAdminList(数据管理);
setMe(me[0]);
}
},[数据管理,加载管理];
useffect(()=>{
const{id}=props.match.params;
锁定博客({
变量:{
身份证件
锁定:锁定
}
}).then(异步({data})=>{
控制台日志(数据);
});
return()=>{
锁定博客({
变量:{
身份证件
锁定:错误
}
}).then(异步({data})=>{
控制台日志(数据);
});
};
},[锁定];
//如果加载数据
if(加载| |加载|管理)
返回(
);
如果(错误)返回错误。;
//更改表格后更新
常数updateField=e=>{
设定状态({
…形式,
[e.target.name]:e.target.value
});
};
//编辑器更新
const onchangeditor=text=>{
const currentText=articleText.text;
const newText=JSON.stringify(text);
如果(currentText!==newText){
//内容发生了变化
if(定时器参考电流){
clearTimeout(timerRef.current);
}
setArticleText({text:newText});
如果(!formValidate()){
timerRef.current=设置超时(()=>{
onSubmitAuto();
}, 10000);
}
}
};
//自动保存
const onSubmitAuto=()=>{
if(定时器参考电流){
clearTimeout(timerRef.current);
}
编辑博客({
变量:{
身份证件
管理员id,
标题
text:articleText.text,
类别
地位
}
}).then(异步({data})=>{
控制台日志(数据);
});
};
//证实
const formValidate=()=>{
const{title,category}=形式;
return!title | |!articleText.text | |!category;
};
//清晰状态
常量重置状态=()=>{
setState({…initialState});
};
返回(
//jsx
)
第一个问题,当调用SubmitAuto时,first useEffect再次运行。我不要这个。
因为我只想让它在第一次安装时工作
第二个问题,如果articleText
状态以前发生过更改,则在进行变异时不会对表单状态中的数据进行变异。但是,如果表单状态先更改,则会对所有数据进行变异。我觉得这个问题和第一个问题是一样的
我希望我能解释一下这个问题/ Ciao,我对第一个问题有一个答案:当触发
onSubmitAuto
时,它调用editBlog
,更改加载
。并且加载
在第一个useffect
deps列表中。
如果您不希望这样,修复可能是这样的:
const isInitialMount = useRef(true);
//first useEffect
useEffect(() => {
if(isInitialMount.current) {
if (!loading && data) {
setState({
title: data.blog.title,
category: data.blog.category,
admin_id: data.blog.admin.id,
status: data.blog.status
});
setArticleText({
text: data.blog.text
});
}
console.log(data);
if (data !== undefined) isInitialMount.current = false;
}
}, [loading, data]);
再见,我对第一个问题有一个答案:当
onSubmitAuto
被触发时,它调用editBlog
,从而更改加载
。并且加载
在第一个useffect
deps列表中。
如果您不希望这样,修复可能是这样的:
const isInitialMount = useRef(true);
//first useEffect
useEffect(() => {
if(isInitialMount.current) {
if (!loading && data) {
setState({
title: data.blog.title,
category: data.blog.category,
admin_id: data.blog.admin.id,
status: data.blog.status
});
setArticleText({
text: data.blog.text
});
}
console.log(data);
if (data !== undefined) isInitialMount.current = false;
}
}, [loading, data]);
首先,当你调用SubmitAuto时,它会再次运行上一个useEffect,因为useEffect已经[locked],你每次更改SubmitAuto上锁定的状态时,它都会运行上一个useEffect。我对锁定没有问题,我从onSubmitAuto上删除了锁定。同样的问题还在继续。我更新了代码。问题在于onSubmitAuto和第一个useEffect@Fernandoramirez首先,当你调用SubmitAuto时,它会再次运行上一个useEffect,因为useEffect已经[锁定],你每次更改SubmitAuto上锁定的状态时,锁定的状态都会运行上一个useEffect。我对锁定没有问题,我从onSubmitAuto上删除了锁定。同样的问题还在继续。我更新了代码。问题在于onSubmitAuto和第一个useEffect@Fernandoramirez感谢您的回答,但是现在setState在第一次加载时不起作用,所以useEffect现在不起作用。当我测试此代码时,“console.log(data)”返回未定义@乔瓦尼·埃斯波西西奥,如果在我的建议之前工作过,也应该在我的建议之后工作。我所做的只是使用bool ref在useffect中执行一次代码。真奇怪。。。如果(!loading&&data)返回false且setState将不执行,则不管怎样,如果数据为null。旧代码在控制台中也有一次未定义,然后数据出现。如何使useQuery数据异步?我不知道这一点,但useEffect正在尝试在装载数据后立即获取数据。旧代码正确加载数据。但是正如我所说,它给出了一次未定义的结果。谢谢你的回答,但是现在setState在第一次加载时不起作用,所以useEffect现在不起作用。当我测试这段代码时,“console.log(data)”返回未定义@乔瓦尼·埃斯波西西奥,如果在我的建议之前工作过,也应该在我的建议之后工作。我所做的只是使用bool ref在useffect中执行一次代码。真奇怪。。。如果(!loading&&data)返回false且setState将不执行,则不管怎样,如果数据为null。旧代码在控制台中也有一次未定义,然后数据出现。如何使useQuery数据异步?我不知道这一点,但useEffect正在尝试在装载数据后立即获取数据。旧代码正确加载数据。但正如我所说,它给出了一个未定义的定义。