简体   繁体   English

更改 UseState Hook React 组件后不重新渲染

[英]After changing UseState Hook React component not re-rendering

I am new at React and i am trying to develop a login page.我是 React 的新手,我正在尝试开发一个登录页面。 I did almost all but I could not re-render after successful login.我几乎完成了所有操作,但成功登录后无法重新渲染。 I need to refresh the page to see the protected content.我需要刷新页面才能看到受保护的内容。 As far as I know, using custom Hook and changing its value should trigger a component re-render but although I change the value of it (token), page is not re-rendered.据我所知,使用自定义 Hook 并更改其值应该会触发组件重新渲染,但是尽管我更改了它的值(令牌),但不会重新渲染页面。 What is the point i missed?我错过了什么?

//App.js

function App() {
  const { token, setToken } = useToken();
  if(!token) {
    return <Login setToken={setToken} />
  }

  return (
    <div className="wrapper">
      <h1>Application</h1>
      <BrowserRouter>
        <Routes>
          <Route path="/" element={<Dashboard />} />
        </Routes>
      </BrowserRouter>
    </div>
  );
}

export default App;
//UseToken.js

export default function useToken() {
  const getToken = () => {
    const tokenString = localStorage.getItem('token');
    const userToken = JSON.parse(tokenString);
    return userToken;
  };

  const [token, setToken] = useState(getToken());

  const saveToken = userToken => {
    localStorage.setItem('token', JSON.stringify(userToken));
    setToken(userToken.token);
  };

  return {
    setToken: saveToken,
    token
  }
}
//Login.js

async function loginUser(credentials) {
  return fetch('http://localhost:8080/user', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(credentials)
  }).then(data => data.json())
  .then(response => response.token)
 }

export default function Login({ setToken }) {
  const [username, setUserName] = useState();
  const [password, setPassword] = useState();

  const handleSubmit = async e => {
    e.preventDefault();
    const token = await loginUser({
      username,
      password
    });
    setToken(token);
  }

  return(
    <div className="login-wrapper">
      <h1>Please Log In</h1>
      <form onSubmit={handleSubmit}>
        <label>
          <p>Username</p>
          <input type="text" onChange={e => setUserName(e.target.value)}/>
        </label>
        <label>
          <p>Password</p>
          <input type="password" onChange={e => setPassword(e.target.value)}/>
        </label>
        <div>
          <button type="submit">Submit</button>
        </div>
      </form>
    </div>
  )
}

Login.propTypes = {
  setToken: PropTypes.func.isRequired
}
//Dashboard.js
export default function Dashboard() {
  const logout = () => {
    localStorage.clear();
  }

  return(
    <div>
      <h2>Dashboard</h2>
      <button type="button" onClick={logout}>Logout</button> 
    </div>
  );
}

In useToken.js在 useToken.js

  const saveToken = userToken => {
    localStorage.setItem('token', JSON.stringify(userToken));
    setToken(userToken.token);
  }

should be replaced to应更换为

  const saveToken = userToken => {
    localStorage.setItem('token', JSON.stringify(userToken));
    setToken(userToken); //userToken.token changed to userToken
  }

Because, there is no variable named as 'token' in userToken object.因为,userToken object 中没有名为“token”的变量。 It is token itself.它本身就是令牌。 So the hook thinks that there is no change and because of that it does not re-render.所以钩子认为没有变化,因此它不会重新渲染。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM