【问题标题】:Why does the state update but I can't access it via hooks in React?为什么状态更新但我无法通过 React 中的钩子访问它?
【发布时间】:2019-10-22 07:05:43
【问题描述】:

我在通过钩子响应时无法访问更新的全局状态。我创建了自定义钩子来摆脱减速器和任何 redux,因为我不喜欢它。一切正常,但我无法访问我的状态。

这是全局状态的设置方式

import React, {useState, useMemo, useContext} from 'react'

function makeStore() {
  // Make a context for the store
  const Context = React.createContext();

  // Make a provider that takes an initialValue
  const Provider = ({ initialValue, children }) => {
    // Make a new state instance (could even use immer here!)
    const [state, setState] = useState(initialValue);
    // Memoize the context value to update when the state does
    const contextValue = useMemo(() => [state, setState], [state]);

    // Provide the store to children
    return <Context.Provider value={contextValue}>{children}</Context.Provider>;
  };

  // A hook to help consume the store
  const useStore = () => useContext(Context);

  return { Provider, useStore };
}

const {Provider, useStore} = makeStore();

export {
  Provider,
  useStore
}

我确保将商店提供程序包裹在 App 组件周围

ReactDOM.render(
  <Router basename="">
    <Provider initialValue={initialState} >
      <App />
    </Provider>
  </Router>,
  document.getElementById("root")
);

App 组件干净,主要用于路由

const App = () => 
    <div className="App">
      <Route exact path="/" component={props => <Landing {...props} />} />
      <Route exact path="/login" component={props => <Login {...props} />} />
      <Route exact path="/register/:id" component={props => <Register {...props} />}/>
      <PrivateRoute path='/:id' Component={<Content />} />
    </div>



export default App

当我点击登录页面时,输入登录信息,然后单击提交,状态会更新。唯一的事情是我无法访问组件内的更新状态。

这里是登录组件

const Login = ({...props}) => {
    const { register, handleSubmit } = useForm()
    const {auth, setAuth} = useAuth()
    const {loginUser} = AuthApi()
    const onSubmit = data => (async () => {
        const response = await loginUser(data)
        setAuth(response, true)
    })()
    useEffect(() => {
        if(auth.isAuthenticated === true)
            props.history.push('/dashboard')
    }, [])
    return(
        <div className="Auth" style={{backgroundImage: 'url(' + background + ')'}}>
            <div className="Login">
                <div className="Auth-Form Login-Form">
                    <div className="Form-Header">
                        <h4>
                            <b>Login</b>
                        </h4>
                    </div>
                    <div className="Form">
                        <form onSubmit={handleSubmit(onSubmit)}>
                            <input 
                                placeholder="Email"
                                name="email"
                                ref={register({
                                    required: "email required"
                                })}
                            />
                            <br/>
                            <input 
                                placeholder="Password"
                                name="password"
                                ref={
                                    register({
                                        required: "password required"
                                    })
                                }
                            />
                            <br />
                            <input id="submit" type="submit" placeholder="Create Profile"/>
                        </form>
                        <p className="">
                            Don't have an account? <Link to="/register/user">Register</Link>
                        </p>
                        <Link to="/" className="">Back to home</Link>
                    </div>
                </div>
            </div>
        </div>
    )
}

export default Login;

这是 useAuth 钩子代码

const useAuth = () => {
    const [{...auth}, setState] = useStore()

    const setAuth = (data, authenticationStatus) => {
        setState(state => {
            state.auth.token = data.token
            state.auth.user = data.user
            state.auth.loading = true
            state.auth.isAuthenticated = authenticationStatus
        })
    }

    return {auth, setAuth}
}

当登录组件中 auth.isAutheticated 的值转换为 true 时,没有任何反应。在提供者中,状态被更新,甚至在 useAuth 钩子中,我在控制台中记录当前状态及其更新。然而,尽管使用了 useEffects,但我无法在登录组件中访问它?有什么我想念的吗?

【问题讨论】:

    标签: reactjs react-hooks global-state


    【解决方案1】:

    此代码仅像 componentdidmount 一样发生 - 一次:

    useEffect(() => {
            if(auth.isAuthenticated === true)
                props.history.push('/dashboard')
        }, [])
    

    改成

     useEffect(() => {
                if(auth.isAuthenticated === true)
                    props.history.push('/dashboard')
            })
    

    【讨论】:

    • 哇,这确实起到了作用!我遇到了另一个问题,当状态被更新并重新呈现为一个空对象时。
    • 可以把日志放到codesandbox里,也可以是活生生的例子
    • 试试 useEffect(() => { if(auth.isAuthenticated === true) props.history.push('/dashboard') },[auth.isAuthenticated])
    猜你喜欢
    • 2021-06-12
    • 1970-01-01
    • 1970-01-01
    • 2021-12-01
    • 2020-04-29
    • 1970-01-01
    • 2021-08-17
    • 2021-02-12
    • 1970-01-01
    相关资源
    最近更新 更多