简体   繁体   English

react-redux:动作不改变商店

[英]react-redux: actions do not change the store

I'm building a react app with redux and I have a problem.我正在使用 redux 构建一个反应应用程序,但我遇到了问题。

I have a component connected to the redux store and even though I dispatch actions those actions are not received from the reducer thus the state won't change.我有一个连接到 redux 存储的组件,即使我调度动作,这些动作也没有从减速器收到,因此 state 不会改变。

Here's the code of the component:这是组件的代码:

import React from "react";
import { connect } from "react-redux";

import { setOrderFilter } from "store/filters";

const mapStateToProps = (state) => {
    return {
        filters: state.entities.filters,
    };
};

const mapDispatchToProps = {
    setOrderFilter,
};

function Filters(props) {
    const { order } = props.filters;

    console.log(setOrderFilter({test: 1}) 
    // {type: "filters/setOrderFilter", payload: {…}}
    // payload: {test: 1}
    // type: "filters/setOrderFilter"

    const handleOrder = (event) => {
        setOrderFilter({ order: event.target.value });
    };

    return (
        <div>
            <label>
                Date order:
                <select value={order} onChange={(e) => handleOrder(e)}>
                    <option value="ascending">ascending</option>
                    <option value="descending">descending</option>
                </select>
            </label>
        </div>
    );
}

export default connect(mapStateToProps, mapDispatchToProps)(Filters);

Here's the filters.js file in the store:这是商店中的filters.js文件:

import { createSlice } from "@reduxjs/toolkit";

const slice = createSlice({
    name: "filters",
    initialState: {
        order: "descending",
    },
    reducers: {
        setOrderFilter: (state, action) => {
            console.log("here");
            state.order = action.payload;
        },
    },
});

export const { setOrderFilter } = slice.actions;

export default slice.reducer;

Everything looks fine, even console.log the action setOrderFilter yields the correct result, but when I change the select in the UI, no action is dispatched and the value doesn't change... the console.log inside the reducer is never printed.一切看起来都很好,即使console.log操作setOrderFilter产生正确的结果,但是当我在 UI 中更改 select 时,不会调度任何操作并且值不会改变......减速器内的console.log永远不会打印.

The store is configured with an api middleware to handle async code:商店配置了一个 api 中间件来处理异步代码:

import axios from "axios";
import * as actions from "store/api";

import getBaseUrl from "helpers/getApiUrl";

const api = ({ dispatch }) => (next) => async (action) => {
    console.log(action)
    if (action.type !== actions.apiCallBegan.type) return next(action);

    ....
};

export default api;

The calls from other entities are printed and visible in the middleware, the one from filters are not even printed there.来自其他实体的调用被打印并在中间件中可见,来自filters的调用甚至没有打印在那里。

What am I missing?我错过了什么?

The problem is in the handleOrder function.问题出在句柄订单 function 中。

const handleOrder = (event) => {
    setOrderFilter({ order: event.target.value });
};

You have to use the connected setOrderFilter .您必须使用连接的setOrderFilter That is in the component's props.那是在组件的道具中。

const handleOrder = (event) => {
    props.setOrderFilter({ order: event.target.value });
};

It's an easy mistake to make when using the mapDispatchToProps shorthand.使用 mapDispatchToProps 速记时很容易犯错误。 There is a function in scope called setOrderFilter , but when you use that, you will just create the action object, but it will not be dispatched to redux. There is a function in scope called setOrderFilter , but when you use that, you will just create the action object, but it will not be dispatched to redux.

I think its the variables names.我认为它的变量名称。 Try this:尝试这个:

state.order = action.order;

if you are using redux-toolkit you can directly use hooks.如果你使用的是 redux-toolkit,你可以直接使用 hooks。

Here seems like you are just calling the action, it's not enough but you also need to dispatch action as well .这里似乎你just calling动作, it's not enough但你还need to dispatch action as well in your case, it's not even reaching a reducer as you are NOT dispatching it that is the issue.在您的情况下,它甚至没有到达减速器,因为您NOT dispatching it ,这就是问题所在。

Try this, It should fix your issue.试试这个,它应该可以解决你的问题。

import React, { useCallback } from "react";
import { useDispatch, useSelector } from "react-redux";
import { setOrderFilter } from "store/filters";

function Filters(props) {
    const dispatch = useDispatch();

    const handleOrder = useCallback ((event) => {
        // you actually need to dispatch action not just call it
        dispatch(setOrderFilter({ order: event.target.value }));
    }, []);

    // ... other code

I hope this will solve your issue我希望这能解决你的问题

If you want a solution in your way then use this如果您想以自己的方式解决问题,请使用它

import React from "react";
import { connect } from "react-redux";

import { setOrderFilter } from "store/filters";

const mapDispatchToProps = (dispatch) => ({
  applyOrderFilter: (filterData) => dispatch(setOrderFilter(filterData))
});

// in your component

function Filters(props) {
    const dispatch = useDispatch();

    const handleOrder = useCallback ((event) => {
        // you can call that prop method
        props.applyOrderFilter({ order: event.target.value }));
    }, []);

    // ... other code
}

export default connect(mapStateToProps, mapDispatchToProps)(Filters);

if any doubt please comment.如有任何疑问,请发表评论。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM