Javascript useContext导致不需要的重新渲染
我在登录表单中遇到了重新登录和内存泄漏问题。目标是有一个组件来检查上下文的JWT是否有效,如果有效则重定向。但是,在登录和更新上下文时,上下文在应该重定向时会导致重新加载。解决这个问题的办法是什么 编辑:问题似乎是我重新提交了两次身份验证:一次在登录中,一次在SecuredLote中。有更优雅的解决方案吗 useValidateToken.js Login.jsJavascript useContext导致不需要的重新渲染,javascript,reactjs,react-router,react-hooks,react-state,Javascript,Reactjs,React Router,React Hooks,React State,我在登录表单中遇到了重新登录和内存泄漏问题。目标是有一个组件来检查上下文的JWT是否有效,如果有效则重定向。但是,在登录和更新上下文时,上下文在应该重定向时会导致重新加载。解决这个问题的办法是什么 编辑:问题似乎是我重新提交了两次身份验证:一次在登录中,一次在SecuredLote中。有更优雅的解决方案吗 useValidateToken.js Login.js 功能登录(道具){ const{token,setToken}=useContext(TokenContext) const[user
功能登录(道具){
const{token,setToken}=useContext(TokenContext)
const[username,setUsername]=useState(“”);
const[password,setPassword]=useState(“”);
const{isLoading:validateLoading,authenticated}=useValidateToken(令牌);
const[shouldRedirect,setShouldRedirect]=useState(false);
const[isLoading,setIsLoading]=useState(false);
const[isInvalid,setIsInvalid]=useState(false);
函数登录(){
设置加载(真);
获取(`/login`,{…})
.then(resp=>resp.json())
。然后(body=>{
if(body.jwt){
setToken(body.jwt);
setShouldRedirect(true);
}否则{
setIsInvalid(真);
setTimeout(函数(){setIsInvalid(false)},3000)
设置加载(假);
}
})
.catch(=>setisload(false));
}
返回验证加载(
//跳过的代码
):shouldRedirect==true | | authenticated==true(
) : (
//跳过的代码
);
}
路由使用自定义组件进行保护。这样做是为了保护路由,并在存在无效令牌时重定向到登录
App.js
//跳过的代码
const[token,setToken]=useState(null);
const{authenticated}=useValidateToken(令牌)
//跳过的代码
函数securedurote({component:component,authenticated,…rest}){
返回(
验证===真(
) : (
)
}
/>
);
}
export default token => {
const [validateLoading, setLoading] = useState(true);
const [authenticated, setAuthenticated] = useState(false);
useEffect(() => {
fetch(`/validate_token`, {
method: "GET",
headers: { Authorization: "Bearer " + token }
})
.then(resp => {
if (resp.ok) setAuthenticated(true);
setLoading(false);
})
.catch(_ => setLoading(false));
}, [token]);
return { validateLoading, authenticated };
};
function Login(props) {
const {token, setToken} = useContext(TokenContext)
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const { isLoading: validateLoading, authenticated } = useValidateToken(token);
const [shouldRedirect, setShouldRedirect] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const [isInvalid, setIsInvalid] = useState(false);
function login() {
setIsLoading(true);
fetch(`/login`, { ... })
.then(resp => resp.json())
.then(body => {
if (body.jwt) {
setToken(body.jwt);
setShouldRedirect(true);
} else {
setIsInvalid(true);
setTimeout(function () { setIsInvalid(false) }, 3000)
setIsLoading(false);
}
})
.catch(_ => setIsLoading(false));
}
return validateLoading ? (
// Skipped code
) : shouldRedirect === true || authenticated === true ? (
<Redirect to={props.location.state ? props.location.state.from.pathname : "/"} />
) : (
<div className="login">
// Skipped code
<LoginButton loading={isLoading} login={login} error={isInvalid} />
</div>
</div>
);
}
// Skipped code
const [token, setToken] = useState(null);
const { authenticated } = useValidateToken(token)
//Skipped code
<SecuredRoute exact path="/add-issue/" component={AddIssue} authenticated={authenticated} />
function SecuredRoute({ component: Component, authenticated, ...rest }) {
return (
<Route
{...rest}
render={props =>
authenticated === true ? (
<Component {...props} {...rest} />
) : (
<Redirect to={{ pathname: "/login", state: { from: props.location } }} />
)
}
/>
);
}