reactjs - 如何使用 React Redux Hooks 加载微调器
问题描述
我正在尝试使用 react-redux 钩子(useSelector 和 useDispatch)加载微调器。我能够获取数据但不能获取加载器(在我的例子中是 showLoader 和 hideLoader)
期望:当我单击刷新按钮时,我想加载微调器(在后台它将刷新数据)。在单击按钮之前,我可以使用 useEffect 挂钩获取数据。
//ActionCreators.js
export const EVENT_LOG = "EVENT_LOG";
export const EVENT_FAILURE = "EVENT_FAILURE";
export const SHOW_LOADER = "SHOW_LOADER";
export const HIDE_LOADER = "HIDE_LOADER";
//Actions.js
import {
EVENT_LOG,
EVENT_FAILURE,
SHOW_LOADER,
HIDE_LOADER,
} from "./actionCreators";
import { readList } from "./APIUtilsNew";
export const readLogs = (path) => {
return (dispatch) => {
readList(path)
.then((data) =>
dispatch(
{
type: EVENT_LOG,
payload: data,
},
console.log("EventLog Actions: ", data)
)
)
.catch((error) => {
dispatch({
type: EVENT_FAILURE,
payload: error,
});
throw error;
});
};
};
export const showLoader = () => (dispatch) => {
dispatch({
type: SHOW_LOADER,
});
};
export const hideLoader = () => (dispatch) => {
dispatch({
type: HIDE_LOADER,
});
};
//Reducers.js
import {
EVENT_LOG,
EVENT_FAILURE,
HIDE_LOADER,
SHOW_LOADER,
} from "../../actionCreators/index";
export const initialState = {
loading: false,
eventData: [],
eventError: false,
};
const eventReducer = (state = initialState, action) => {
switch (action.type) {
case EVENT_LOG:
return {
...state,
eventData: action.payload,
};
case EVENT_FAILURE:
return {
...state,
eventError: action.payload,
};
case HIDE_LOADER:
return {
...state,
loading: false,
};
case SHOW_LOADER:
return {
...state,
loading: true,
};
default:
return state;
}
};
export default eventReducer;
//React Component
import React, { useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { readLogs, showLoader, hideLoader } from "./eventActions";
import { FormattedMessage } from "react-intl";
import { XGrid } from "@material-ui/x-grid";
import { CSVLink } from "react-csv";
import IconBtn from "./IconBtn";
import MaterialTheme from "./MaterialTheme";
import { ThemeProvider as MuiThemeProvider } from "@material-ui/core/styles";
import Refresh from "./Refresh";
export default function EventsLog() {
const dispatch = useDispatch();
const eventLogs = useSelector(
(state) => state.eventReducer.eventData.data || []
);
const show = useSelector((state) => state.eventReducer.loading);
const hide = useSelector((state) => state.eventReducer.loading);
useEffect(() => {
dispatch(readLogs("/events"));
}, [dispatch]);
const update = () => {
dispatch(showLoader());
dispatch(hideLoader());
};
let rows = eventLogs.map((obj, index) => {
return (rows = {
id: index + 1,
Time: obj.time,
dateTime: obj.dateTime,
ID: obj.deviceId
});
});
const columns = [
{
field: "Time",
flex: 1,
type: "dateTime",
renderHeader: () => <FormattedMessage id={"time"} />
},
{
field: "dateTime",
flex: 1,
type: "dateTime",
renderHeader: () => <FormattedMessage id={"dateTime"} />
},
{
field: "ID",
flex: 1,
renderHeader: () => <FormattedMessage id={"id"} />
}
];
return (
<div>
<h1>
<FormattedMessage id="event.eventLog" />
<span>
<IconBtn iconLabel="refresh" />
</span>
<CSVLink data={rows} filename={"Log.csv"}>
<IconBtn iconLabel="cloud_download" onClick={update} />
</CSVLink>
</h1>
<div style={{ height: "90%", width: "100%" }}>
<MuiThemeProvider theme={MaterialTheme}>
<Refresh />
<XGrid
pageSize={50}
rowsPerPageOptions={[25, 50, 100]}
rows={rows}
columns={columns}
pagination={true}
hideFooterSelectedRowCount={true}
/>
</MuiThemeProvider>
</div>
</div>
);
}
这是我的微调器所在的组件。我想在加载微调器时获取这个组件
//Refresh Component
import React from "react";
export default function Refresh() {
return <div>Spinner....</div>;
}
我在网上看到几个例子,我发现一切都在类组件中
// component Example
class FullPageLoader extends Component {
state = { }
render() {
const {loading} = this.props;
if(!loading) return null;
return (
<div class="loader-container">
<div className="loader">
<img src={LoaderGif} />
</div>
</div>
);
}
}
const mapStateToProps = state => ({ loading: state.application.loading })
export default connect(mapStateToProps)(FullPageLoader);
// Another Component
updateProfile = () =>{
this.props.dispatch( showLoader() )
Axios.post(`https://jsonplaceholder.typicode.com/users`, { user : { name : 'Test User' } })
.then(res => {
console.log( res );
this.props.dispatch( hideLoader() )
})
/* setTimeout(() => {
this.props.dispatch( hideLoader() )
}, 2000); */
}
<Button bsStyle="info" pullRight fill onClick={this.updateProfile} >
Update Profile
</Button>
有人可以帮助我如何将上述类转换为基于函数的组件,而不是使用 mapStateToProps 来挂钩(或)请告诉我如何使用 react-redux 挂钩加载微调器。感谢您的帮助!
解决方案
更简单的方法是在动作本身中显示和隐藏加载器。在 promise 之前,将 Loader 设置为 true。然后然后抓住你可以隐藏装载机。
export const readLogs = (path) => {
return (dispatch) => {
showLoader();
readList(path)
.then((data) => {
hideLoader();
dispatch(
{
type: EVENT_LOG,
payload: data,
},
console.log("EventLog Actions: ", data)
)
})
.catch((error) => {
hideLoader();
dispatch({
type: EVENT_FAILURE,
payload: error,
});
throw error;
});
};
};
如果必须在组件本身中完成,您可以添加延迟而不是立即调用它们。这里似乎没有发生任何动作。
const update = () => {
dispatch(showLoader());
setTimeout(() => {
dispatch(hideLoader());
}, 1000);
};
推荐阅读
- polymer - 聚合物测试失败,“铬未能最大化”
- javascript - 如何正确修复节点中的渲染 ejs
- angular - 使用 Ng 模型选择下拉菜单不反映 Internet Explorer 11 中的更改
- php - 如何通过 Laravel 为 S3 实现 Amazon V4 签名?
- linq - MVC 多对多仅在代码中首先获取具有某种类型的实体
- php - laravel 多表单路由
- r - 当需要的多个条件在另一个表中时执行求和?
- selenium - 如果多个编辑按钮具有相同的 HTML 编码,我将如何单击 Selenium 中的按钮
- typo3 - TYPO3 9.5.3 - 显示多次尝试访问不存在路由的日志错误
- javascript - 仅带有可拖动标题的弹出窗口