【问题标题】:React Redux - How to do a proper loading screen using React and Redux on url changeReact Redux - 如何在 url 更改时使用 React 和 Redux 进行正确的加载屏幕
【发布时间】:2020-06-03 06:45:26
【问题描述】:

我正在开发一个使用 React + Redux 的网络应用程序。但是,我在加载屏幕上苦苦挣扎。基本上,我对 redux 商店的初始状态是这样的。

const initialState = {
    project: {},
    projects: [],
    customers: [],
    vendors: [],
    customer: {},
    vendor: {},
    loading: false
};

我的一个减速器的一个例子是这个

const fetchSalesProject = (state, action) => {
    return updateObject(state, {
        project: action.payload,
        loading: false
    });
}

const reducer = (state = initialState, action) => {
    switch (action.type) {
        case actionTypes.FETCH_SALES_PROJECT: return fetchSalesProject(state, action);
    default:
        return state;

updateObject 在哪里

export const updateObject = (oldObject, updatedProperties) => {
    return {
        ...oldObject,
        ...updatedProperties
    }
}

这是我的操作(axiosInstance 只是 axios 的自定义插件,用于包含身份验证所需的标头,但与普通 axios api 调用完全相同)

export const fetchSalesProject = (id) => (dispatch) => {
    axiosInstance
        .get(`/sales-project/detail/${id}/`)
        .then((res) => {
            dispatch({
                type: FETCH_SALES_PROJECT,
                payload: res.data,
            });
        })
        .catch((err) => dispatch(returnErrors(err.response.data, err.response.status)));
};

export const showLoader = (area) => (dispatch) => {
    dispatch({
        type: SHOW_LOADER,
        area: area ? area : true
    });
};

其中参数区域只是在加载仅在页面上的特定区域上呈现的情况下(与此问题无关,因此当调用 showLoader 时,不会传入任何参数,因此该区域将为这个问题设置为真)

这是我的组件

componentDidMount() {
    this.props.showLoader()
    this.props.fetchSalesProject(this.props.match.params.id)
};

这是我的 mapStateToProps

const mapStateToProps = state => ({
     project: state.api.project,
     loading: state.api.loading
})

这是我的条件渲染

render() {
    return (
        !this.props.loading ?
            {... whatever content within my page }
        : { ...loading screen }

基本上,我面临的问题是,当我第一次加载这个组件时,会出现错误,因为我的 this.props.project 将是一个空的 {}(由于 initialState)。原因是在 showLoader 动作被 componentDidMount 完全调度之前,组件渲染,因此由于 this.props.loading 仍然设置为 false 的 initialState,条件渲染通过并且 this.props.project 将是渲染(但是由于它是空的,我尝试在渲染中访问的各种键将是未定义的,因此会引发错误)。

我尝试了各种方法来克服这个问题,但似乎没有一个是最佳解决方案。例如,我尝试将加载的初始状态设置为任意数字,例如。 0,只有在this.props.loading === false时才渲染页面,也就是取数据之后。但是,当我进入新页面时会出现问题,例如另一个名为 CustomerDetail 的组件。安装该组件后,this.props.loading 将为 false 而不是 0,因为它之前是由我使用的前一个组件 (SalesProjectDetail) 操作的。因此,当条件渲染在实际获取任何数据之前通过时,会出现同样的错误。

我尝试的另一种方法是使用组件状态来处理条件渲染。例如,我只在所有调度完成后才设置组件状态 done : true 。但是,我觉得混​​合组件状态和像 Redux 这样的状态管理系统并不是一个好习惯,因此希望看看是否有任何解决方案可以解决我的问题,只使用 Redux。

我正在寻找解决我的问题的方法,即仅在获取数据之后才呈现内容,并且在获取数据之前,应该呈现加载屏幕。感谢所有帮助,而且我是 React 尤其是 Redux 的新手,所以如果我在应该如何解决这个问题上被误导,请引导我走上正确的道路。提前谢谢大家!

【问题讨论】:

    标签: reactjs redux react-redux


    【解决方案1】:

    可以有更多的方法来做到这一点。但是要继续你的地方州计划......

    我认为如果您使用本地状态来跟踪加载完成或正在进行中,则没有问题。 正如您已经说过的,您可以拥有一个本地状态变量。 在 dispatch 之前将该变量设置为 loading=true 然后使用 async/await 来获取数据,然后将 loading 设置回 false。

    我认为它对你有用。

    【讨论】:

    • 好的,我会继续这样做,但同时我想到了一种新方法,我不确定它是否会更好。基本上处于我的初始状态,正在加载:{}。每当我加载一个新页面时,我都会添加一个新的加载键。例如,如果我导航到一个 salesproject 页面,我会添加一个新键“salesproject”来加载 {'salesproject': true}。一旦为该页面完成加载,它将被设置为 false。条件渲染将跟踪加载中的特定键,这解决了我的问题。与组件状态相比,您认为这会是一个更简洁的解决方案吗?
    猜你喜欢
    • 2019-05-20
    • 2020-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-09
    • 2018-06-06
    • 2017-03-14
    相关资源
    最近更新 更多