我尝试调用的操作/ reducer 不起作用。它似乎并没有真正按照我调用它的方式读取该函数。问题出在deleteWorkout函数中。
我尝试过使用mapDispatchToProps,并且尝试直接从操作中调用操作。 src-index.js
import React from 'react';
import { createStore } from 'redux';
import allReducer from './reducers';
import { Provider } from 'react-redux';
import ReactDOM from 'react-dom';
import throttle from 'lodash/throttle';
// import registerServiceWorker from './registerServiceWorker';
import App from './App';
import { loadState, saveState } from './localStorage';
const persistedState = loadState();
const store = createStore(
allReducer,
persistedState,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
store.subscribe(throttle(() => {
saveState({
workoutList: store.getState().workoutList
});
}, 100));
ReactDOM.render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
// registerServiceWorker();
reducer -index.js
import { combineReducers } from 'redux'
import switchLogin from './SwitchLogin'
import workoutList from './WorkoutList'
import { reducer as AddWorkout } from 'redux-form'
const allReducers = combineReducers({
switchLogin,
workoutList,
form: AddWorkout,
})
export default allReducers;
WorkoutItem 类
import React, { Component } from "react";
import ExpansionPanel from "@material-ui/core/ExpansionPanel";
import ExpansionPanelSummary from "@material-ui/core/ExpansionPanelSummary";
import ExpansionPanelDetails from "@material-ui/core/ExpansionPanelDetails";
import ExpansionPanelActions from "@material-ui/core/ExpansionPanelActions";
import TableHead from "@material-ui/core/TableHead";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import TableRow from "@material-ui/core/TableRow";
import Table from "@material-ui/core/Table";
import Button from "@material-ui/core/Button";
import Typography from "@material-ui/core/Typography";
// import { MuiThemeProvider } from "material-ui/styles";
import Dialog from "@material-ui/core/Dialog";
import DialogActions from "@material-ui/core/DialogActions";
import DialogContent from "@material-ui/core/DialogContent";
import DialogContentText from "@material-ui/core/DialogContentText";
import DialogTitle from "@material-ui/core/DialogTitle";
import ExerciseList from "./ExerciseList";
// import EditWorkoutItem from "./EditWorkoutItem";
import * as workoutActionCreators from '../../actions';
import { bindActionCreators } from 'redux';
import { connect } from "react-redux";
import moment from "moment";
export default class WorkoutItem extends Component {
state = {
open: false
};
handleSelectedPanel = () => {
this.props.onSelectedPanel(this.props.workout.id);
};
// Opens the page
handleClickOpen = () => {
this.setState({ open: true });
};
// Cancels the changes and closes the page
handleClose = () => {
this.setState({ open: false });
};
deleteWorkout = id => {
console.log(this);
this.setState({ open: false });
this.props.removeWorkout(id);
};
render() {
const { workout } = this.props;
const { id, name, duration, exerciselist } = workout;
const date = moment(workout.date).format("L");
return (
<ExpansionPanel style={styles.panel} id={id} onChange={this.handleSelectedPanel}>
<ExpansionPanelSummary>
<Typography variant="button" style={styles.header}>
{name}
</Typography>
<Typography variant="button" style={styles.header}>
{date}
</Typography>
<Typography align="right" style={styles.header}>
~{duration} mins
</Typography>
</ExpansionPanelSummary>
<ExpansionPanelDetails>
<Table size="medium" style={styles.table}>
<TableHead>
<TableRow>
<TableCell padding="none">Name</TableCell>
<TableCell padding="none" align="right">
# of sets
</TableCell>
<TableCell padding="none" align="right">
average reps
</TableCell>
<TableCell padding="none" align="right">
weight
</TableCell>
</TableRow>
</TableHead>
<TableBody>
{exerciselist.map(exercise => (
<ExerciseList key={exercise.id} exercise={exercise} />
))}
</TableBody>
</Table>
<ExpansionPanelActions disableSpacing style={styles.actionButton}>
{/* <MuiThemeProvider>
<EditWorkoutItem id={id} />
</MuiThemeProvider> */}
<>
<Button size="small" disableRipple onClick={this.handleClickOpen}>
Remove
</Button>
<Dialog
open={this.state.open}
onClose={this.handleClose}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
>
<DialogTitle id="alert-dialog-title">
{"Are you sure?"}
</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description">
This will permanently remove the workout. This action cannot
be undone.
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={this.handleClose} color="primary">
Cancel
</Button>
<Button
onClick={() => this.deleteWorkout(id)}
color="primary"
autoFocus
>
Yes, Remove It
</Button>
</DialogActions>
</Dialog>
</>
</ExpansionPanelActions>
</ExpansionPanelDetails>
</ExpansionPanel>
);
}
}
const mapDispatchToProps = dispatch => {
return { ...bindActionCreators(workoutActionCreators, dispatch) };
};
connect(
null,
mapDispatchToProps
)(WorkoutItem);
行动:
export const removeWorkout = id => ({ type: 'REMOVE_WORKOUT', id })
reducer :
case 'REMOVE_WORKOUT':
console.log(action.id)
return state = {
...state,
workoutlist: state.workoutlist.filter((workout) => workout.id !== action.id)
}
没有错误消息。但当我使用 console.log 时它返回正确的 id 并且它确实关闭了文本框。这就是我知道它停在函数处的方式
最佳答案
第一个主要问题是您没有调用正确的“调度程序”函数,而是调用原始函数。
将您的deleteWorkout更改为:
deleteWorkout = id => {
console.log(id);
this.setState({ open: false });
this.props.removeWorkout(id);
};
第二个主要问题是,您没有导出已连接的 Redux 容器,而是导出尚未连接到 Redux 的 React 组件。
从类声明中删除“导出默认值”:
class WorkoutItem extends Component {
// ...
并将其添加到 Redux 容器中:
export default connect(
null,
mapDispatchToProps
)(WorkoutItem);
编辑(这是实现bindActorCreators函数思想的可选更改。bindActorCreators也可以将单个 Action 创建者作为第一个参数)。 而且您似乎将单个 Action 创建者作为第一个参数传递给 redux 函数 bindActionCreators,但该函数采用 Action 创建者的映射。 https://redux.js.org/api/bindactioncreators
您有两种解决方法:
- 不要使用bindActionCreators(如果你是redux初学者更好)
const mapDispatchToProps = dispatch => {
return { removeWorkout: (id) => dispatch(removeWorkout(id)) };
};
- 正确使用bindActionCreators
// you need to import your action crerators in single object
import * as workoutActionCreators from 'path_to_your_action_creators';
// ...
// bind all action creators with dispatch function and the bound action creators map to props
const mapDispatchToProps = dispatch => {
return { ...bindActionCreators(workoutActionCreators, dispatch) };
};
关于javascript - 在这种情况下,如何正确地从 reducer /操作中调用函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57898408/