【问题标题】:React-redux component update state attributes after async saga calls from reducerReact-redux 组件在来自 reducer 的异步 saga 调用后更新状态属性
【发布时间】:2019-10-24 02:28:24
【问题描述】:

我正在尝试使用 react-redux 堆栈开发一个简单的图像列表组件。 这是我的操作、reducers、saga 和组件根定义 -

// Actions 

export const getImageListData = () => ({
    type: IMAGE_LIST_GET_DATA
});

export const getImageListDataSuccess = (data) => {
    console.log("ACTION::SUCCESS", data);
    return ({
        type: IMAGE_LIST_GET_DATA_SUCCESS,
        payload: data
    });
};

// Reducers

export default (state = INIT_STATE, action) => {
    console.log("REDUCER::", state, action);
    switch (action.type) {

        case IMAGE_LIST_GET_DATA: return { ...state, isLoading: true };
        case IMAGE_LIST_GET_DATA_SUCCESS: return { ...state, items: action.payload.data, isLoading: false };

        default: return { ...state };
    }
}

// Sagas

import imagesData from "Data/images.json";

function* loadImages() {
    try {
        const response = yield call(loadImagesAsync);
        console.log("SAGA:: ", response);
        yield put(getImageListDataSuccess(response));
    } catch (error) {
        console.log(error);
    }
}

const loadImagesAsync = async () => {
        const contacts = imagesData;
        return await new Promise((success, fail) => {
            setTimeout(() => {
                success(contacts);
            }, 2000);
        }).then(response => response).catch(error => error);

};

export function* watchGetImages() {
    console.log("ACTION::INIT", IMAGE_LIST_GET_DATA);
    yield takeEvery(IMAGE_LIST_GET_DATA, loadImages);
}

export default function* rootSaga() {
    yield all([
        fork(watchGetImages)
    ]);
}

现在在我正在调用的组件中 - getImageListData 操作

并使用此 mapStateToProps 和连接提供程序 -

const mapStateToProps = ({ ImageList }) => {
    const {items} = ImageList;
    return {items};
};

export default connect(
    mapStateToProps,
    {
        getImageListData
    }
)(ImageListLayout);

我正在将图像列表响应映射到组件道具。 我的组件定义如下 -

class ImageListLayout extends Component {
    constructor(props) {
        super(props);

        this.state = {
            displayMode: "imagelist",
            pageSizes: [8, 12, 24],
            selectedPageSize: 8,
            categories:  [
                {label:'Cakes',value:'Cakes',key:0},
                {label:'Cupcakes',value:'Cupcakes',key:1},
                {label:'Desserts',value:'Desserts',key:2},
            ],
            orderOptions:[
                {column: "title",label: "Product Name"},
                {column: "category",label: "Category"},
                {column: "status",label: "Status"}
            ],
            selectedOrderOption:  {column: "title",label: "Product Name"},
            dropdownSplitOpen: false,
            modalOpen: false,
            currentPage: 1,
            items: [],
            totalItemCount: 0,
            totalPage: 1,
            search: "",
            selectedItems: [],
            lastChecked: null,
            displayOptionsIsOpen: false,
            isLoading:false
        };
    }
    componentDidMount() {
        this.dataListRender();
    }

    dataListRender() {
        this.props.getImageListData();
    }

    render() {
        ...
    }
}

现在在我的组件中,我可以正确访问从 reducer 获得的 this.props.items,操作为 IMAGE_LIST_GET_DATA_SUCCESS,但我还想更新一些状态变量,如 isLoading, currentPage, totalItemCount, totalPage,因为这些属于该组件本身,而不是他们的父母我不想将它们映射到道具,但想更新组件的状态并触发重新渲染。

有人可以告诉我我应该怎么做才能解决这个问题,还是我在这里遗漏了什么?

【问题讨论】:

    标签: javascript reactjs redux react-redux redux-saga


    【解决方案1】:

    在您当前的设置中,我认为您没有理由在该州拥有 isLoading 等。你应该把它映射到道具:

    const mapStateToProps = ({ ImageList, isLoading }) => {
        const {items} = ImageList;
        return {items, isLoading};
    };
    

    我不明白你为什么说“因为这些属于这个组件本身而不是它们的父级,所以我不想将它们映射到道具,而是想更新组件的状态并触发重新渲染。 "父母与这里有什么关系?

    【讨论】:

    • 阅读stackoverflow.com/questions/27991366/… 这让我觉得我不应该对属于组件且父母不需要的属性使用道具,因为将它们从顶级容器传递给组件是浪费的,因为中间组件不需要使用这些。因此,我认为我需要将这些变量保存在组件状态本身中。如果我想从 reducer 更新状态,为什么对 reducer 中的状态所做的更改没有反映在 render 方法中?
    猜你喜欢
    • 2017-03-22
    • 1970-01-01
    • 2019-02-25
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    • 2018-07-26
    • 1970-01-01
    • 2017-08-08
    相关资源
    最近更新 更多