简体   繁体   English

反应钩子:显示从孩子加载微调器

[英]react hooks : show loading spinner from child

I'm new with React and I want to understand hooks.我是 React 的新手,我想了解钩子。

Expected result : have 2 global functions to show/hide a loading spinner from anywhere in components tree.预期结果:有 2 个全局函数来显示/隐藏组件树中任何位置的加载微调器。

Actual result : When I call showLoader and hideLoader in useEffect of ChildPage, it is looping on the render.实际结果:当我在 ChildPage 的useEffect中调用showLoaderhideLoader时,它在渲染上循环。

After reading several tutorials and many answers on this site, I would like to understand what's wrong in my code.在阅读了本网站上的几个教程和许多答案后,我想了解我的代码有什么问题。 (I have already tried Redux but I had the same result). (我已经尝试过 Redux,但结果相同)。

App.js应用程序.js

const StateProvider = ({ reducer, initialState, children }) => (
  <StateContext.Provider value={reducer}>{children}</StateContext.Provider>
);
export const useStateValue = () => useContext(StateContext);

const loaderReducer = (state = false, action) => {
  switch (action.type) {
    case "show_loader":
      return { isFetching: true };
    case "hide_loader":
      return { isFetching: false };
    default:
      throw new Error("Unexpected action");
  }
};

const App = props => {
  const initialState = { isFetching: false };

  const [state, dispatch] = useReducer(loaderReducer, initialState);

  return (
    <StateProvider initialState={initialState} reducer={{ dispatch }}>
      <div className="App">
        {state.isFetching ? (
          <ReactLoading
            className="loader"
            type="cylon"
            color="#4caf50"
            height={64}
            width={64}
          />
        ) : (
          <ChildPage />
        )}
      </div>
    </StateProvider>
  );
};

export default App;

StateContext.js状态上下文.js

const StateContext = createContext(null);
export default StateContext;

childPage.js子页面.js

const ChildPage = props => {
  const { dispatch } = useContext(StateContext);

  const showLoader = useCallback(() => dispatch({ type: "show_loader" }), []);
  const hideLoader = useCallback(() => dispatch({ type: "hide_loader" }), []);

  useEffect(() => {
    async function fetchExample() {
      showLoader();
      await fetch("https://jsonplaceholder.typicode.com/todos/1")
        .then(response => response.json())
        .then(json => console.log(json));
      hideLoader();
    }
    fetchExample();
  }, [showLoader, hideLoader]);
  //same thing with [] as second arg

  return (
    <div>
      <h1>hello in ChildPage</h1>
    </div>
  );
};

export default ChildPage;

Your ChildPage got destroyed while loading?您的 ChildPage 在加载时被破坏了?

I've read your code.我已经阅读了你的代码。 You used conditional expression to control the UI.您使用条件表达式来控制 UI。 That is the very reason you got loop renderings.这就是您获得循环渲染的真正原因。

How to understand it?怎么理解?

Every time the Effect callback got invoked, showLoader is called which leads ChildPage to be unconstructed.每次调用 Effect 回调时, showLoader调用showLoader导致 ChildPage 未showLoader After the fetch promise settled, hideLoader is called which leads ChildPage re-constructed and then the Effect callback will be applied. fetch promise 确定后, hideLoader导致 ChildPage 重新构造,然后应用 Effect 回调。

You set a loop here.你在这里设置一个循环。 :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM