【发布时间】:2021-03-01 14:52:09
【问题描述】:
我正在设计一个前端应用程序,我需要了解行业标准或最佳实践,以便在页面刷新期间调用后端 API。
这是一个简单的设置。
- 三个 Navlinks Home、DisplayRepo、RedirectToRepo 由 react-router 提供服务。
- 主页链接是一个登陆页面。
- 在componentMount期间的首页,需要使用Axios,redux-thunk从后端API获取数据。
数据保存在 store 中,由 redux-persist 提供(保存在本地存储中。在页面刷新期间可用)。此数据通常在 DisplayRepo、RedirectToRepo 链接中使用,在显示在 UI 上之前,在两个页面上执行的一些规范化不同。 当用户单击 DisplayRepo 或 RedirectToRepo 链接时,数据在商店中可用。用户使用 useSelector 获取数据并显示。
到目前为止一切顺利。
我需要在以下几点上提供一些意见和说明:-
- 当用户刷新页面时,尽管数据已经在存储中可用,redux-persist/redux-thunk 会在内部调用后端。我的理解是,由于本地存储上已经有数据,可以调用后端来获取数据吗?
- 这里的最佳实践应该是什么?另一种方法是检查本地存储上的数据,如果不可用,则应使用 API 调用后端。但是如果 LS 有过时的数据怎么办?
主页:-
const Login = (props) => {
const classes = useStyles(props);
const dispatch = useDispatch();
const history = useHistory();
const [uname, setUname] = useState('');
const { successNotific } = buttonNotification;
const { enqueueSnackbar } = props;
const inputRef = useRef();
const submitBtn = useRef();
useEffect(() => {
inputRef.current.focus();
}, []);
const onChangeHandler = (e) => setUname(e.target.value);
const handleKeyDown = (e) => {
if (e.key === 'Enter') {
e.target.name === 'email' && submitBtn.current.focus();
}
};
return (
<FormControl className={classes.signInForm}>
<Header />
<Box className={classes.inputContainer}>
<input
type='email'
name='email'
ref={inputRef}
className='username'
onKeyDown={handleKeyDown}
placeholder='Enter GitHub UserName'
value={uname}
onChange={onChangeHandler}
/>
<Button
key={successNotific}
disabled={uname.length === 0}
className={classes.btn}
variant='contained'
color='primary'
name='submit'
ref={submitBtn}
onClick={() =>
fetchRepoForNewUser(uname, enqueueSnackbar, dispatch, history)
}
>
Submit
</Button>
</Box>
</FormControl>
);
};
当用户点击提交时被初始化的 API 调用:-
export const fetchRepoForNewUser = async (
userNameInUrl,
enqueueSnackbar,
dispatch,
history
) => {
const { successNotific, errorNotific, loadingNotific } = buttonNotification;
enqueueSnackbar(loadingNotific.message, { variant: loadingNotific.variant });
window.__MUI_USE_NEXT_TYPOGRAPHY_VARIANTS__ = true;
const isValidGitHubUser = await dispatch(getRepoAction(userNameInUrl));
if (isValidGitHubUser) {
enqueueSnackbar(successNotific.message, {
variant: successNotific.variant,
});
history.push(`/displayuserrepo/${userNameInUrl.toLowerCase()}`);
} else {
enqueueSnackbar(errorNotific.message, { variant: errorNotific.variant });
}
};
请求通过 dispatch action 到达 Redux thunk:-
`export const getRepoAction = (uname) => {
const url = `${GITHUB_API_URL}/${uname}/repos`;
return async (dispatch) => {
dispatch({ type: GET_USER_REPO_LOADING });
try {
alert('calleddd');
const response = await axios.get(url, axiosHeader);
if (response?.status && response.data.length > 0) {
dispatch({ type: GET_USER_REPO_SUCCESS, data: response.data });
dispatch({ type: GET_USERNAME_SUCCESS, data: uname });
return true;
} else {
dispatch({ type: GET_USER_REPO_FAILED });
return false;
}
} catch (error) {
dispatch({ type: GET_USER_REPO_FAILED });
dispatch({ type: GET_USERNAME_FAILED });
return false;
}
};
};
`
ListOfRepo 组件:-
const ListOfRepo = (props) => {
const { enqueueSnackbar } = props;
const history = useHistory();
const getUserNameFromRedux = (state) => state.loginReducer.uname;
const username = useSelector(getUserNameFromRedux);
const getUserRepoFromRedux = (state) => state.appReducer.data;
const rowData = useSelector(getUserRepoFromRedux);
const userNameInUrl =
history.location.pathname !== '/' &&
history.location.pathname.split('/')[2];
useEffect(() => {
userNameInUrl !== username &&
fetchRepoForNewUser(userNameInUrl, enqueueSnackbar, dispatch, history);
}, []);
const classes = useStyles(props);
const dispatch = useDispatch();
const onClickHandler = () =>
dispatch({ type: GET_USER_REPO_SUCCESS, data: [] });
return (
<Box className={classes.listOfRepoContainer}>
<GridDisplay
rowData={rowData}
columnHeaders={columnHeaders}
LinkComponent={LinkComponent}
/>
<Button
disabled={rowData.length === 0}
className={classes.resetBtn}
variant='contained'
color='primary'
onClick={onClickHandler}
>
Clear Repositories
</Button>
</Box>
);
};
【问题讨论】:
标签: reactjs redux react-redux redux-thunk redux-persist