React Hooks-根据状态有条件地渲染组件

时间:2020-01-30 21:02:53

标签: javascript reactjs react-hooks

我正在尝试创建带有钩子的基本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未捕获(承诺)错误: 无效的挂接调用。挂钩只能在主体内部使用 功能组件。

如何检查user是否处于状态,并基于带有Dashboard的呈现react-hooks组件?

2 个答案:

答案 0 :(得分:2)

将状态移出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();
   //...
 }

答案 1 :(得分: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;