从组件中的useState多次调用状态更新程序会导致多次重新渲染
我第一次尝试使用React钩子,直到我意识到当我获取数据并更新两个不同的状态变量(数据和加载标志)时,我的组件(数据表)都呈现了两次,即使两次调用都看起来不错状态更新程序发生在同一功能中。这是我的api函数,它将两个变量都返回给我的组件。
const getData = url => {    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(true);
    useEffect(async () => {
        const test = await api.get('/people')
        if(test.ok){
            setLoading(false);
            setData(test.data.results);
        }
    }, []);
    return { data, loading };
};
在普通的类组件中,您只需要调用一次即可更新状态,该状态可以是一个复杂的对象,但是“钩子方式”似乎是将状态分成较小的单元,其副作用似乎是多次分别更新时呈现。有什么想法可以减轻这种情况吗?
回答:
您可以将loading状态和data状态组合为一个状态对象,然后可以进行一次setState调用,并且只会有一个渲染。
 与setStatein类组件不同,setStatereturn from
useState不会合并具有现有状态的对象,而是会完全替换该对象。如果要进行合并,则需要读取以前的状态,然后自己将其与新值合并。请参考文档。
在您确定性能问题之前,我不必担心过度调用渲染。呈现(在React上下文中)和将虚拟DOM更新提交到实际DOM是不同的事情。这里的渲染是指生成虚拟DOM,而不是更新浏览器DOM。React可能会批量setState调用并用最终的新状态更新浏览器DOM。
const {useState, useEffect} = React;function App() {
  const [userRequest, setUserRequest] = useState({
    loading: false,
    user: null,
  });
  useEffect(() => {
    // Note that this replaces the entire object and deletes user key!
    setUserRequest({ loading: true });
    fetch('https://randomuser.me/api/')
      .then(results => results.json())
      .then(data => {
        setUserRequest({
          loading: false,
          user: data.results[0],
        });
      });
  }, []);
  const { loading, user } = userRequest;
  return (
    <div>
      {loading && 'Loading...'}
      {user && user.name.first}
    </div>
  );
}
ReactDOM.render(<App />, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
回答:
const {useState, useEffect} = React;function useMergeState(initialState) {
  const [state, setState] = useState(initialState);
  const setMergedState = newState =>
    setState(prevState => Object.assign({}, prevState, newState)
  );
  return [state, setMergedState];
}
function App() {
  const [userRequest, setUserRequest] = useMergeState({
    loading: false,
    user: null,
  });
  useEffect(() => {
    setUserRequest({ loading: true });
    fetch('https://randomuser.me/api/')
      .then(results => results.json())
      .then(data => {
        setUserRequest({
          loading: false,
          user: data.results[0],
        });
      });
  }, []);
  const { loading, user } = userRequest;
  return (
    <div>
      {loading && 'Loading...'}
      {user && user.name.first}
    </div>
  );
}
ReactDOM.render(<App />, document.querySelector('#app'));
<script src="https://unpkg.com/react@16.7.0-alpha.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.7.0-alpha.0/umd/react-dom.development.js"></script>
<div id="app"></div>
以上是 从组件中的useState多次调用状态更新程序会导致多次重新渲染 的全部内容, 来源链接: utcz.com/qa/424059.html








