如何停止 React.useEffect 的副作用? [复制]

Posted

技术标签:

【中文标题】如何停止 React.useEffect 的副作用? [复制]【英文标题】:how to stop the side effect of React.useEffect? [duplicate] 【发布时间】:2021-07-28 09:02:00 【问题描述】:

当我在我的网络应用程序中继续路由 /login 时,它会触发一个 useEffect,它不应该因为此时没有任何状态被更改,请查看我的代码并告诉我我在哪里我错了

function Login()
const history = useHistory();

var [email, setEmail] = React.useState("");
var [password, setPassword] = React.useState("");
var [isLoggedIn, setLogin] = React.useState(false);
var [allTodosList, setList] = React.useState([]);

React.useEffect(()=>
    console.log("triggered")
, [isLoggedIn])

const sendLogin = async(event) => 
    try 
        var data = 
            Email : email,
            Password: password,
        
        const response = await axios.post("/api/login", data);
        if (response.data.verified === true)
            const todoList = response.data.todos;
            setLogin(true);
        
        else
            alert("Invalid credentials please try again");
        
    
    catch(err)
        console.log("there is an error while sending login data via post");
        console.log(err);
    

return(
    <div className = "login-form">
        <form>
            <input  
             type="text" className = "emailbox"
             placeholder = "Email" value = email
             onChange = (event) => setEmail(event.target.value)/>
            <input type="password" className = "passwordbox"
            name="password" id="password" 
            placeholder= "password" value = password
            onChange = (event) => setPassword(event.target.value)/>
            <span className = "login-button"><Button variant = "cantained"color = "secondary"
            onClick = sendLogin> Login</Button></span>
        </form>
    </div>
)

export default Login;

当我使用反应路由继续这个组件时,useEffect 以某种方式被触发并触发了控制台日志.. 请告诉我如何阻止这个 useEffect 触发,除非状态改变???

【问题讨论】:

所有挂钩在初始渲染时运行。 useEffect 钩子也不例外。回调将被调用。如果您不想在初始渲染上运行某些逻辑,则可以使用 ref 来保存在第一次渲染后切换为 true 的值。 【参考方案1】:

它在加载时以及状态发生变化时触发。您应该有条件地检查状态。

React.useEffect(()=>
    console.log("triggered")
    if (isLoggedIn) 
       console.log('isLoggedIn is true')
        
    //else, just don't do anything.

, [isLoggedIn])

如果你熟悉 React 类生命周期方法,你可以想 useEffect Hook 为 componentDidMount、componentDidUpdate 和 componentWillUnmount 组合。 https://reactjs.org/docs/hooks-effect.html

这解释了为什么在组件安装、更新(基于依赖项或空数组 - 仅调用一次)以及将被卸载(清理)时调用 useEffect。

【讨论】:

是的,它会解决我的问题,但我只是好奇为什么会这样 更新答案。【参考方案2】:

请看这个例子。 https://stackblitz.com/edit/react-eelqp2

我创建了一个钩子useMountedRef 并检查mountedRef 是否为真以避免副作用。

我之所以使用setTimeout是为了做一个合理的延迟,这样我们就可以确保在所有初始useEffects之后ref值都设置为true。

【讨论】:

以上是关于如何停止 React.useEffect 的副作用? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

数据更改后停止执行函数(React,useEffect)

[react] useEffect和useLayoutEffect有什么区别?

如何在 React useEffect 中更改路由器

使用 Jest 和酶时如何在 React.useEffect 钩子上获得线路覆盖?

React useEffect 无限循环获取数据 axios

React useEffect 如何监视和更新状态? [复制]