简体   繁体   English

React Redux:在分派之前调用使用选择器

[英]React Redux : use Selector is called before dispatch

I'm creating a react app with redux.我正在使用 redux 创建一个 React 应用程序。
I need the lists of french departements for all pages in my app, so I put it in redux state.我需要我应用程序中所有页面的法语部门列表,所以我把它放在 redux state 中。

I dispatch the action in the App component in the useEffect hook (Note I use an other useEffect in the component, but when the action is in the other block it's not working too)我在 useEffect 挂钩中分派 App 组件中的操作(注意我在组件中使用了另一个 useEffect,但是当操作在另一个块中时它也不起作用)

I have a page where I need to use this list, so I select it with the useSelector hook.我有一个需要使用此列表的页面,因此我使用 useSelector 挂钩将其 select。 But it returns an empty object, I have an error telling me dpts.map is not a function但它返回一个空的 object,我有一个错误告诉我dpts.map is not a function

I think the action is dispatching after the page has rendered, because I when I log the response of the api call in the action, it appears after the log of the useSelector result.我认为该操作是在页面呈现后调度的,因为当我在操作中记录 api 调用的响应时,它出现在 useSelector 结果的日志之后。

I'm using another state property in another page, but it seems to work with the other page.我在另一个页面中使用另一个 state 属性,但它似乎适用于另一个页面。

App.jsx应用程序.jsx

const dispatch = useDispatch();
useEffect(() => {
        dispatch(getDpts());
}, [dispatch])

Here is the action associated with:这是与以下内容相关的操作:

dpts.actions.js dpts.actions.js

import axios from "axios";

export const GET_DPTS = "GET_DPTS";
export const getDpts = () => {
    return async (dispatch) => {
        try {
            const res = await axios({
                method: "get",
                url: "https://geo.api.gouv.fr/departements",
            });
            console.log("done : " + res)
            dispatch({ type: GET_DPTS, payload: res.data });
        } catch (err) {
            (err) => console.log("DPTS FETCH ERROR --- " + err);
        }
    };
};

Map.jsx Map.jsx

function DptCtl() {
    // Control
    const map = useMap();

    // List of dpts and provinces
    const dpts= useSelector(dptsSelector);
    console.log(dpts);

    return (
        <>
            <input type="text" list="dpt-ctl-list" placeholder="Filtrer par département"/>
            <datalist id="dpt-ctl-list">
                {dpts.map((dpt, index) => 
                    <option value={dpt.code} key={index}>{dpt.nom}</option>
                )}
            </datalist>
        </>
    )
}

It depends on how you are initializing your state in the reducer.这取决于您如何在减速器中初始化 state。

for example you create a reducer with this initial state:例如,您使用初始 state 创建一个减速器:

const initialState={}

later, based on actions, the state changes to this:后来,根据操作,state 更改为:

   {dpts:someDataArray}

the problem is that you have a dpts.map somewhere in your app, since dpts is undefined in the beginning you receive that error that dpts.map is not a function.问题是你的应用程序中有一个dpts.map ,因为一开始dptsundefined的,你会收到dpts.map不是 function 的错误。

the solution to this is simply put dpts in the initialState as an empty array:对此的解决方案只是将 dpts 作为空数组放入 initialState 中:

    const initialState={dpts:[]}

if that is not the issue with your code, meaning dpts isn't undefined in the initialState, it is probably initialized as a string or an object which don't have map methods.如果这不是您的代码的问题,这意味着dpts在 initialState 中未定义,则它可能被初始化为字符串或 object,它没有map方法。

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

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