useEffect 永不停止 运行
useEffect never stops running
我相信这个问题已经被问过一百万次了。我已经查看了至少 50% 的回复。但是 none 对我有用。
我有这个组件:
import React, { useState } from 'react';
import './App.css';
import { FormPaper, FormWrapper } from "teton-frontend-components/dist";
import { TextField } from '@material-ui/core';
import Network from "./Network";
import { TetonButton } from "teton-frontend-components";
import useDeepCompareEffect from "./deepCompare";
const logo = require("./timer.png");
function App() {
const [ids, setIds] = useState([]);
const [word, setWord] = useState("");
const [loading, setLoading] = useState(false);
const [id, setId] = useState("");
useDeepCompareEffect(() => {
Network.getWordIds().then(ids => {
setIds(ids.data.data);
});
}, []);
useDeepCompareEffect(() => {
const id = window.location.href.split("/")[window.location.href.split("/").length - 1];
if (id) {
getWordWithId(id);
}
}, [])
const getWord = () => {
setLoading(true);
const id = ids[Math.floor(Math.random() * ids.length)]._id;
Network.getWordById(id).then(word => {
const href = window.location.href;
window.location.href = href.split("/")[0] + id;
setWord(word.data.data);
}).catch(err => {
console.error(err);
}).finally(() => {
setLoading(false);
});
};
const getWordWithId = id => {
Network.getWordById(id).then(word => {
const href = window.location.href;
window.location.href = href.split("/")[0] + id;
setWord(word.data.data);
}).catch(err => {
console.error(err);
}).finally(() => {
setLoading(false);
});
};
return (
<div className="App">
<FormPaper width={"30%"} margin={"5% auto"} logo={logo} children={
<div>
<FormWrapper children={
<div>
<p>Encavis Zusammenhalt Tabu</p>
<br/>
Wort
<br/>
<TextField color={"primary"} disabled={true} variant={"outlined"}
style={{margin: "0 0 2% 0"}} value={word.word}/>
<br/>
Verbotene Wörter
<br/>
<TextField color={"primary"} disabled={true} variant={"outlined"}
value={word.taboos ? word.taboos[0] : ""}/>
<br/>
<TextField color={"primary"} disabled={true} variant={"outlined"}
value={word.taboos ? word.taboos[1] : ""}/>
<br/>
<TextField color={"primary"} disabled={true} variant={"outlined"}
value={word.taboos ? word.taboos[2] : ""}/>
<br/>
<TextField color={"primary"} disabled={true} variant={"outlined"}
value={word.taboos ? word.taboos[3] : ""}/>
<br/>
<TextField color={"primary"} disabled={true} variant={"outlined"}
value={word.taboos ? word.taboos[4] : ""}/>
<br/>
<TetonButton text={"Neues Wort"} variant={"contained"} color={"primary"}
onClick={() => getWord()} disabled={false} loading={loading}
margin={"2% 0 0 0"}/>
</div>
}/>
</div>
}/>
</div>
);
}
export default App;
我想点击按钮,然后获取一个词并将其设置到字段中。这很好用。我还需要 href
参数不要被忽略,因为我需要页面在 href
中加载带有该 ID 的页面。但是,当单击按钮时,我不希望发生这种情况。所以我读到 [] 作为使用效果的依赖数组只会 运行 渲染一次。但是现在,一旦单击按钮或页面加载了 href
中的 id,我就会无限重新加载。我怎样才能阻止这个? deepCompare
只是为了让我也可以检查对象。我也尝试了依赖数组的所有组合。这简直就是讨厌我。
感谢您的帮助!
编辑:深度比较代码
import * as _ from "lodash";
import { useEffect, useRef } from "react";
const deepCompareEquals = (a, b) => {
return _.isEqual(a, b);
};
const useDeepCompareMemoize = value => {
const ref = useRef();
if (!deepCompareEquals(value, ref.current)) {
ref.current = value
}
return ref.current
};
const useDeepCompareEffect = (callback, dependencies) => {
useEffect(callback, useDeepCompareMemoize(dependencies));
};
export default useDeepCompareEffect;
刚发现。
您正在使用 window.location.href = href.split("/")[0] + id;
,它将始终重新加载页面,当然这将导致您提到的问题。
这些东西你必须使用 react router
。
我相信这个问题已经被问过一百万次了。我已经查看了至少 50% 的回复。但是 none 对我有用。
我有这个组件:
import React, { useState } from 'react';
import './App.css';
import { FormPaper, FormWrapper } from "teton-frontend-components/dist";
import { TextField } from '@material-ui/core';
import Network from "./Network";
import { TetonButton } from "teton-frontend-components";
import useDeepCompareEffect from "./deepCompare";
const logo = require("./timer.png");
function App() {
const [ids, setIds] = useState([]);
const [word, setWord] = useState("");
const [loading, setLoading] = useState(false);
const [id, setId] = useState("");
useDeepCompareEffect(() => {
Network.getWordIds().then(ids => {
setIds(ids.data.data);
});
}, []);
useDeepCompareEffect(() => {
const id = window.location.href.split("/")[window.location.href.split("/").length - 1];
if (id) {
getWordWithId(id);
}
}, [])
const getWord = () => {
setLoading(true);
const id = ids[Math.floor(Math.random() * ids.length)]._id;
Network.getWordById(id).then(word => {
const href = window.location.href;
window.location.href = href.split("/")[0] + id;
setWord(word.data.data);
}).catch(err => {
console.error(err);
}).finally(() => {
setLoading(false);
});
};
const getWordWithId = id => {
Network.getWordById(id).then(word => {
const href = window.location.href;
window.location.href = href.split("/")[0] + id;
setWord(word.data.data);
}).catch(err => {
console.error(err);
}).finally(() => {
setLoading(false);
});
};
return (
<div className="App">
<FormPaper width={"30%"} margin={"5% auto"} logo={logo} children={
<div>
<FormWrapper children={
<div>
<p>Encavis Zusammenhalt Tabu</p>
<br/>
Wort
<br/>
<TextField color={"primary"} disabled={true} variant={"outlined"}
style={{margin: "0 0 2% 0"}} value={word.word}/>
<br/>
Verbotene Wörter
<br/>
<TextField color={"primary"} disabled={true} variant={"outlined"}
value={word.taboos ? word.taboos[0] : ""}/>
<br/>
<TextField color={"primary"} disabled={true} variant={"outlined"}
value={word.taboos ? word.taboos[1] : ""}/>
<br/>
<TextField color={"primary"} disabled={true} variant={"outlined"}
value={word.taboos ? word.taboos[2] : ""}/>
<br/>
<TextField color={"primary"} disabled={true} variant={"outlined"}
value={word.taboos ? word.taboos[3] : ""}/>
<br/>
<TextField color={"primary"} disabled={true} variant={"outlined"}
value={word.taboos ? word.taboos[4] : ""}/>
<br/>
<TetonButton text={"Neues Wort"} variant={"contained"} color={"primary"}
onClick={() => getWord()} disabled={false} loading={loading}
margin={"2% 0 0 0"}/>
</div>
}/>
</div>
}/>
</div>
);
}
export default App;
我想点击按钮,然后获取一个词并将其设置到字段中。这很好用。我还需要 href
参数不要被忽略,因为我需要页面在 href
中加载带有该 ID 的页面。但是,当单击按钮时,我不希望发生这种情况。所以我读到 [] 作为使用效果的依赖数组只会 运行 渲染一次。但是现在,一旦单击按钮或页面加载了 href
中的 id,我就会无限重新加载。我怎样才能阻止这个? deepCompare
只是为了让我也可以检查对象。我也尝试了依赖数组的所有组合。这简直就是讨厌我。
感谢您的帮助!
编辑:深度比较代码
import * as _ from "lodash";
import { useEffect, useRef } from "react";
const deepCompareEquals = (a, b) => {
return _.isEqual(a, b);
};
const useDeepCompareMemoize = value => {
const ref = useRef();
if (!deepCompareEquals(value, ref.current)) {
ref.current = value
}
return ref.current
};
const useDeepCompareEffect = (callback, dependencies) => {
useEffect(callback, useDeepCompareMemoize(dependencies));
};
export default useDeepCompareEffect;
刚发现。
您正在使用 window.location.href = href.split("/")[0] + id;
,它将始终重新加载页面,当然这将导致您提到的问题。
这些东西你必须使用 react router
。