我是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;
答案 0 :(得分:1)
您的ChildPage在加载时被破坏了吗?
我已经阅读了您的代码。您使用条件表达式来控制UI。这就是您获得循环渲染的原因。
如何理解?
每次调用Effect回调时,都会调用showLoader
,这将导致ChildPage被取消构造。在完成获取承诺后,将调用hideLoader
,它将导致ChildPage重建,然后将应用Effect回调。
您在此处设置了循环。 :)