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

时间:2019-12-04 00:00:19

标签: reactjs react-hooks

我是React的新手,我想了解钩子。

预期结果 :具有2个全局功能,可从组件树中的任何位置显示/隐藏加载微调器。

实际结果 :当我在ChildPage的useEffect中调用 showLoader hideLoader 时,它在渲染。

在阅读了本站点上的一些教程和许多答案之后,我想了解我的代码有什么问题。 (我已经尝试过Redux,但结果相同)。

App.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

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

childPage.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;

1 个答案:

答案 0 :(得分:1)

您的ChildPage在加载时被破坏了吗?

我已经阅读了您的代码。您使用条件表达式来控制UI。这就是您获得循环渲染的原因。

如何理解?

每次调用Effect回调时,都会调用showLoader,这将导致ChildPage被取消构造。在完成获取承诺后,将调用hideLoader,它将导致ChildPage重建,然后将应用Effect回调。

您在此处设置了循环。 :)