连接组件从 Redux store 读取,但 action creators 不更新它
Connected component reads from Redux store, but action creators don't update it
我有一个连接的组件,它从 Redux 商店获取信息并将其显示在屏幕上。但是每当我尝试发送一个动作来更新状态时,它最终并没有做任何事情:
AppSettings.js
import {
MINUTE_MS,
MINUTE_S,
} from '../constants'
import {
decrementSession,
incrementSession,
} from './timerSlice'
import React from 'react'
import { connect } from 'react-redux'
import equal from 'fast-deep-equal'
/* eslint-disable no-useless-constructor */
export class AppSettings extends React.Component {
constructor(props) {
super(props)
this.state = {
sessionLength: this.props.sessionLength,
}
}
componentDidUpdate(prevProps) {
if (!equal(this.props, prevProps)) {
this.setState((_, props) => {
return {
sessionLength: props.sessionLength,
};
})
}
}
render() {
let sessionLength = Math.floor(this.props.sessionLength / MINUTE_MS) % MINUTE_S
sessionLength = ('0' + sessionLength).slice(-2)
return (
<div>
<div>
<h3>
session
</h3>
<button
id='sessionUp'
onClick={this.props.incrementSession}
>
up
</button>
<h4>
{sessionLength}
</h4>
<button
id='sessionDown'
onClick={this.props.decrementSession}
>
down
</button>
</div>
</div>
);
}
}
function mapStateToProps(state) {
return {
sessionLength: state['sessionLength'],
};
}
function mapDispatchToProps() {
return {
decrementSession,
incrementSession,
};
}
export default connect(
mapStateToProps,
mapDispatchToProps,
)(AppSettings)
timerSlice.js
import {
DEFAULT_SESSION,
MINUTE_MS,
} from '../constants'
import { createSlice } from '@reduxjs/toolkit'
export const timerSlice = createSlice({
name: 'timer',
initialState: {
sessionLength: DEFAULT_SESSION,
},
reducers: {
decrementSession(state) {
state['sessionLength'] -= MINUTE_MS
},
incrementSession(state) {
state['sessionLength'] += MINUTE_MS
},
}
})
export const {
decrementSession,
incrementSession,
} = timerSlice.actions
export default timerSlice.reducer
store.js
import { configureStore } from '@reduxjs/toolkit'
import reducer from '../features/timerSlice'
const store = configureStore({
reducer: reducer
})
export default store
在初始渲染时,组件会很好地从存储中读取,并显示适当的值。单元测试表明组件在传递新属性时会更新屏幕上呈现的值。我的单元测试还表明,只要按下按钮,就会调用相应的函数。我在浏览器中 运行 我的应用程序,它显示 Redux 商店根本没有更新。
为什么我的商店在我尝试从我的组件发送操作时没有响应?
当前设置中的 mapDispatchToProps
似乎有问题。我通过将其转换为函数组件并使用 useDispatch
调用操作来使其工作。
本地状态是不必要的。直接使用从redux中选择的值即可。
export const AppSettings = () => {
const dispatch = useDispatch();
const sessionLength = useSelector(state => state.sessionLength);
const seconds = Math.floor(sessionLength / MINUTE_MS) % MINUTE_S
const secondsString = ('0' + seconds).slice(-2)
return (
<div>
<div>
<h3>
session
</h3>
<button
id='sessionUp'
onClick={() => dispatch(incrementSession())}
>
up
</button>
<h4>
{secondsString}
</h4>
<button
id='sessionDown'
onClick={() => dispatch(decrementSession())}
>
down
</button>
</div>
</div>
);
}
我有一个连接的组件,它从 Redux 商店获取信息并将其显示在屏幕上。但是每当我尝试发送一个动作来更新状态时,它最终并没有做任何事情:
AppSettings.js
import {
MINUTE_MS,
MINUTE_S,
} from '../constants'
import {
decrementSession,
incrementSession,
} from './timerSlice'
import React from 'react'
import { connect } from 'react-redux'
import equal from 'fast-deep-equal'
/* eslint-disable no-useless-constructor */
export class AppSettings extends React.Component {
constructor(props) {
super(props)
this.state = {
sessionLength: this.props.sessionLength,
}
}
componentDidUpdate(prevProps) {
if (!equal(this.props, prevProps)) {
this.setState((_, props) => {
return {
sessionLength: props.sessionLength,
};
})
}
}
render() {
let sessionLength = Math.floor(this.props.sessionLength / MINUTE_MS) % MINUTE_S
sessionLength = ('0' + sessionLength).slice(-2)
return (
<div>
<div>
<h3>
session
</h3>
<button
id='sessionUp'
onClick={this.props.incrementSession}
>
up
</button>
<h4>
{sessionLength}
</h4>
<button
id='sessionDown'
onClick={this.props.decrementSession}
>
down
</button>
</div>
</div>
);
}
}
function mapStateToProps(state) {
return {
sessionLength: state['sessionLength'],
};
}
function mapDispatchToProps() {
return {
decrementSession,
incrementSession,
};
}
export default connect(
mapStateToProps,
mapDispatchToProps,
)(AppSettings)
timerSlice.js
import {
DEFAULT_SESSION,
MINUTE_MS,
} from '../constants'
import { createSlice } from '@reduxjs/toolkit'
export const timerSlice = createSlice({
name: 'timer',
initialState: {
sessionLength: DEFAULT_SESSION,
},
reducers: {
decrementSession(state) {
state['sessionLength'] -= MINUTE_MS
},
incrementSession(state) {
state['sessionLength'] += MINUTE_MS
},
}
})
export const {
decrementSession,
incrementSession,
} = timerSlice.actions
export default timerSlice.reducer
store.js
import { configureStore } from '@reduxjs/toolkit'
import reducer from '../features/timerSlice'
const store = configureStore({
reducer: reducer
})
export default store
在初始渲染时,组件会很好地从存储中读取,并显示适当的值。单元测试表明组件在传递新属性时会更新屏幕上呈现的值。我的单元测试还表明,只要按下按钮,就会调用相应的函数。我在浏览器中 运行 我的应用程序,它显示 Redux 商店根本没有更新。
为什么我的商店在我尝试从我的组件发送操作时没有响应?
当前设置中的 mapDispatchToProps
似乎有问题。我通过将其转换为函数组件并使用 useDispatch
调用操作来使其工作。
本地状态是不必要的。直接使用从redux中选择的值即可。
export const AppSettings = () => {
const dispatch = useDispatch();
const sessionLength = useSelector(state => state.sessionLength);
const seconds = Math.floor(sessionLength / MINUTE_MS) % MINUTE_S
const secondsString = ('0' + seconds).slice(-2)
return (
<div>
<div>
<h3>
session
</h3>
<button
id='sessionUp'
onClick={() => dispatch(incrementSession())}
>
up
</button>
<h4>
{secondsString}
</h4>
<button
id='sessionDown'
onClick={() => dispatch(decrementSession())}
>
down
</button>
</div>
</div>
);
}