页面加载时未分派 Redux 状态

Redux state not dispatched on page load

我找不到在页面加载时没有调度我的 redux 状态的原因,即使组件挂载时有调度事件

这是我的问题的一个基本示例:

export const SET_SITE_NAME = "SET_SITE_NAME";

操作:

import {SET_SITE_NAME} from "./AppBarTypes";

export const setSiteName = (state) => dispatch => {
    dispatch({
        type: SET_SITE_NAME,
        payload: state
    })
}

减速器:

import {SET_SITE_NAME} from "./AppBarTypes";

const initialState = {
    state: "Dashboard"
}

export const appBarReducer = (state = initialState, action) => {
    switch(action.type) {
        case SET_SITE_NAME:
            return {
                ...state,
                state: action.payload
            };
        default:
            return state;
    }
}

基本用法:

function ProjectsList(props) {
   
    useEffect(() => {
        props.setSiteName("Projects");
    }, []);

    return (
        <Main open={props.drawer.state}>
        </Main>
    );
}

ProjectsList.propTypes = {
    setSiteName: PropTypes.func.isRequired
};

const mapStateToProps = state => ({
    projects: state.projects,
    drawer: state.drawer
});

export default connect(mapStateToProps, {
    getProjects,
    setSiteName
})(withRouter(ProjectsList));

根据我能够调试的内容,setSiteName 函数运行并且它始终接收到正确的状态。 此外,如果我导航到站点上的其他组件并返回到该组件,它会完美地加载状态,所以我假设实现是正确的。

编辑

我创建了一个可以追溯问题的工作示例。 https://stackblitz.com/edit/react-sf1fmj?file=src%2FApp.js

问题与 useMediaQuery 有关。正如您在示例中看到的,如果您取消注释该部分,将显示默认的 redux 状态 'Dashboard' 而不是设置的 'Projects' 状态。

虽然我不知道为什么会导致这个问题以及如何解决它。如您所见,在这个例子中我什至没有使用那个值,只是查询它...

我认为您的中间件缺少 React Thunk https://github.com/reduxjs/redux-thunk。 这样,您可以使用以下语法:

function incrementAsync() {
  return dispatch => {
    setTimeout(() => {
      // Yay! Can invoke sync or async actions with `dispatch`
      dispatch(increment())
    }, 1000)
  }
}

编辑

我相信你错过了 dispatch...你基本上可以通过两种方式做到这一点:从字面上调用 dispatch 来调度你的动作,或者使用 mapDispatchToProps 函数映射你的调度动作,如下所示:


const mapDispatchToProps = (dispatch) => ({
    siteName: ()=> dispatch(siteNameAction())
})


export default connect(mapStateToProps, mapDispatchToProps)(MyComponent)

所以使用上面显示的方法,您可以简单地调用 this.props.siteName()

我需要改变这个:

const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)');

对此:

const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)', { noSsr: true });

根据文档,如果您不进行任何服务器端渲染,可以将其设置为 false:

Options.noSsr (Boolean [optional]): Defaults to false. In order to perform the server-side rendering reconciliation, it needs to render twice. A first time with nothing and a second time with the children. This double pass rendering cycle comes with a drawback. It's slower. You can set this flag to true if you are not doing server-side rendering.