在 React Developer Tool 中显示来自 useState 的状态变量的名称

IT技术 javascript reactjs react-hooks
2021-05-21 14:21:30

我在学习 ,我使用创建了一系列状态变量useState,在尝试调试并查看其值时,我发现 React Developer Tool 没有显示分配给状态变量的名称,而是显示文本状态,这很不方便,因为无法从中识别哪个变量是试图调试的变量的开头

在此处输入图片说明

更新 1

这是当前的源代码

import React, { useState, useEffect, Fragment } from "react";

function Main() {
  const [data, setData] = useState({ hits: [] });
  const [query, setQuery] = useState("redux");
  const [url, setUrl] = useState(
    "https://hn.algolia.com/api/v1/search?query=redux"
  );
  const [isLoading, setIsLoading] = useState(false);
  const [isError, setIsError] = useState(false);

  useEffect(() => {
    const fetchData = async () => {
      setIsError(false);
      setIsLoading(true);

      try {
        const response = await fetch(url);
        const json = await response.json();

        setData(json);
      } catch (e) {
        setIsError(true);
      }

      setIsLoading(false);
    };

    fetchData();
  }, [url]);

  return (
    <Fragment>
      <form
        onSubmit={event => {
          setUrl(`http://hn.algolia.com/api/v1/search?query=${query}`);
          event.preventDefault();
        }}
      >
        <input value={query} onChange={event => setQuery(event.target.value)} />
        <button type="submit">Search</button>
      </form>

      {isError && <div>Something went wrong ...</div>}

      {isLoading ? (
        <div>Loading...</div>
      ) : (
        <ul>
          {data.hits.map(item => (
            <li key={item.objectID}>
              <a href={item.url}>{item.title}</a>
            </li>
          ))}
        </ul>
      )}
    </Fragment>
  );
}

export default Main;

我在 React Developer 工具中得到了这个

在此处输入图片说明

更新 2

我正在使用 Firefox 68

React Developer Tool 是否有可能显示使用创建的状态变量的名称useState

4个回答

看到这个问题:

https://github.com/facebook/react-devtools/issues/1215#issuecomment-479937560

这是使用钩子时开发工具的正常行为。

我询问了库作者,因为我也希望它显示我的状态变量名称。这就是他所说的:

@cbdeveloper 我还没有想到让 DevTools 能够像您要求的那样显示变量名称的好方法。DevTools 无法读取函数的私有变量,更改 API 以支持传入显示名称会增加组件代码的大小。它对我来说似乎也没有必要,更像是拥有它。

无论如何,这个总括性问题不是进行此类讨论的最佳场所。如果你对此有强烈的感觉,我建议开一个新的 issue。

从“正常”useState hook实现:

const [users, setUser] = useState([]);
const [profile, setProfile] = useState([]);
const [repo, setRepo] = useState([]);
const [loading, setLoading] = useState(false);
const [alert, setAlert] = useState(false);

您可以将其“转换”为:

const [state, setState] = useState({ users: [], profile: [], repo: [], loading: false, alert: false });

你会得到以下结果:

在此处输入图片说明

并且set the state您可以使用rest operator( source 1 / source 2 ) 和state您想要设置的:

// ...state => unchanged states
// alert => state we want to change
setState(state => ({ ...state, alert: true }));

将其用作prop

const {
 users,
 profile,
 repo,
 loading,
 alert
} = state;

<SomeComponent loading={loading} alert={alert} />

您看到React docs 此处并搜索:Should I use one or many state variables?

您可以使用useDebugValue在您自己的钩子中显示自定义标签:

const format = ({ label, value }) =>
  label + ': ' + (typeof value === 'object' ? JSON.stringify(value) : value);

const useNamedState = (label, initialState) => {
  const states = useState(initialState);
  useDebugValue({ label, value: states[0] }, format);
  return states;
};

用法

const [name, setName] = useState('bob');
const [age, setAge] = useState(11);
const [address, setAddress] = useState('London, United Kingdom');
const [isVirgin, setIsVirgin] = useState(false);
const [isMale, setIsMale] = useState(true);
const [hobbies, setHobbies] = useState(['gaming', 'hiking', 'cooking']);
const [friendList, setFriendList] = useState(['bob']);

在此处输入图片说明

const [name, setName] = useNamedState('name', 'bob');
const [age, setAge] = useNamedState('age', 11);
const [address, setAddress] = useNamedState('address', 'London, United Kingdom');
const [isVirgin, setIsVirgin] = useNamedState('isVirgin', false);
const [isMale, setIsMale] = useNamedState('isMale', true);
const [hobbies, setHobbies] = useNamedState('hobbies', ['gaming', 'hiking', 'cooking']);
const [friendList, setFriendList] = useNamedState('friendList', ['bob']);

在此处输入图片说明

代码沙盒演示

嗯,我不知道为什么它不显示名称,但是如果我尝试创建一系列状态变量,有时我只是将一个 state 和 setState 变量初始化为一个空对象。我不确定这是否是最好的方法,但也许在您的开发工具中,它会在您展开时显示状态属性名称。

import React from "react";

export default function App(props) {
  // Initializing the state
  const [state, setState] = React.useState({});
  
  // Changing the state
  setState({ ...state, text1: "hello world", text2: "foobar" });
  
  return (
    <div>
      {state.text1}
      <br />
      {state.text2}
    </div>
  );
}