【问题标题】:React Hooks - render component conditionally based on state [duplicate]React Hooks - 根据状态有条件地渲染组件
【发布时间】:2020-05-16 13:37:41
【问题描述】:

我正在尝试使用钩子创建一个基本的react 功能组件。

import React, { useState, useEffect } from 'react';
import Header from 'test-header';
import Dashboard from 'test-dashboard';
import { api } from '../api';

function storeUser(user) {
  if (user) {
    localStorage.user = JSON.stringify(user);
  } else {
    delete localStorage.user;
  }
}

async function login() {
  const [error, setError] = useState([]);
  const [user, setUser] = useState([]);

  try {
    const user = await api({
      endpoint: 'identity/login',
      method: 'POST',
      json: {
        email: 'test@abc.com',
        password: '12345'
      }
    });
    setUser(user);
    storeUser(user);
  } catch (err) {
    setError(err);
  }
}

function Container() {
  return (
    <div>
      <Header />
      <input type="submit" value="Login" onClick={login}></input>
      {/* if user sets in state then render <Dashboard /> else render error message  */}
    </div>
  );
}

export default Container;

在这里,test-header 组件发布为npm 包工作正常。当我单击Login 按钮时,我收到此错误:

react-dom.development.js?61bb:16178 未捕获(承诺)错误: 无效的挂钩调用。 Hooks 只能在 a 的主体内部调用 功能组件。

我如何检查user 是否已设置为状态,并基于带有react-hooks 的渲染Dashboard 组件?

【问题讨论】:

标签: javascript reactjs react-hooks


【解决方案1】:

将状态移出login。将钩子移动到另一个钩子中。在功能组件中调用该钩子:

  function useUser() {
    const [error, setError] = useState([]);
    const [user, setUser] = useState([]);

    async function login() {
      try {
        const user = await api({   endpoint: 'identity/login', method: 'POST', json: { email: 'test@abc.com',  password: '12345'  }   });
        setUser(user);
        storeUser(user);
      } catch (err) { setError(err);  }
   }
   return { user, error, login };
 }


 function Container() {
   const { user, error, login } = useUser();
   //...
 }

【讨论】:

  • 感谢您提供干净代码的答案。我明白了在组件的顶层拥有状态的意义。接受上一个答案,因为它首先发布并解决了相同的问题。
【解决方案2】:

您没有从功能组件调用钩子。希望以下内容能解决您的疑虑。

import React, {useState, useEffect} from 'react';
import Header from 'test-header';
import Dashboard from 'test-dashboard';
import {api} from '../api';

const Container = props => {
  const [error, setError] = useState([]);
  const [user, setUser] = useState([]);
  function storeUser(user) {
    if (user) {
      localStorage.user = JSON.stringify(user);
    } else {
      delete localStorage.user;
    }
  }
  async function login() {
    try {
      const user = await api({
        endpoint: 'identity/login',
        method: 'POST',
        json: {
          email: 'test@abc.com',
          password: '12345',
        },
      });
    // call setUser only if credentials are correct
      if (validUser) {
        setUser(user);
        storeUser(user);
      }
    } catch (err) {
      setError(err);
    }
  }
  return (
    <div>
      <Header />
      <input type="submit" value="Login" onClick={login}></input>
      {user.length > 0 ? <Dashboard /> : error.length > 0 ? <Error /> : null}
    </div>
  );
};

export default Container;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-11
    • 2020-02-09
    • 1970-01-01
    • 2017-02-22
    相关资源
    最近更新 更多