2021-12-09

Tech Programing

程式人小天地

After changing UseState Hook React component not re-rendering

1 min read


I am new at React and i am trying to develop a login page. 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. 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>
  );
}



Source link

資料來源:Stackoverflow

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *