页面加载时未分派 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.
我找不到在页面加载时没有调度我的 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.