【问题标题】:How do you properly call a function from the reducer/actions in this context?在这种情况下,您如何正确地从 reducer/actions 调用函数?
【发布时间】:2019-09-12 00:55:46
【问题描述】:

我试图调用的动作/减速器不起作用。它似乎并没有以我调用它的方式实际读取函数。问题出在 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;

锻炼项目类

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 })

减速器:

        case 'REMOVE_WORKOUT':
            console.log(action.id)
            return state = {
                ...state,
                workoutlist: state.workoutlist.filter((workout) => workout.id !== action.id)
        }

没有错误信息。但是当我使用 console.log 并且它确实关闭了文本框时它返回了正确的 ID。我就是这样知道它在函数处停止的

【问题讨论】:

  • 如果你使用mapDispatchToProps你不能直接调用函数。你叫它this.props.removeWorkout(id)

标签: javascript redux react-redux material-ui


【解决方案1】:

第一个主要问题是您调用的不是正确的“调度程序”函数,而是原来的函数。

将您的 deleteWorkout 更改为:

deleteWorkout = id => {
    console.log(id);
    this.setState({ open: false });
    this.props.removeWorkout(id);
  };

第二个主要问题是您没有导出已连接的 Redux 容器,而是您的 React 组件仍未连接到 Redux。

从你的类声明中删除“导出默认值”:

class WorkoutItem extends Component {
// ...

并将其添加到 Redux 容器中:

export default connect(
    null,
    mapDispatchToProps
)(WorkoutItem);

EDIT(这是实现bindActorCreators函数思想的可选更改。bindActorCreators也可以将单个动作创建者作为第一个参数)。 而且您似乎将单个动作创建者作为第一个参数传递给 redux 函数 bindActionCreators,但该函数采用动作创建者的映射。 https://redux.js.org/api/bindactioncreators

你有两个选择来解决它:

  1. 不要使用 bindActionCreators(如果你是 redux 初学者更好)
const mapDispatchToProps = dispatch => {
  return { removeWorkout: (id) => dispatch(removeWorkout(id)) };
};
  1. 正确使用 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) };
};

【讨论】:

  • 我试过了,并在上面的评论中描述了发生的事情
  • 您遇到了另一个问题,抱歉我第一次没有看到。之后看看我的编辑:“而且看起来……”
  • 我尝试了这两种方法,但它们仍然返回相同的错误...这是否意味着我在其他地方完全做错了?
  • 大概,你能发布整个文件 WorkoutItem.js(带导入)和你在应用程序中初始化 redux 的文件(商店、reducers 等)吗?
  • 是的,感谢您的帮助!我已经迷失了太久了哈哈
猜你喜欢
  • 1970-01-01
  • 2022-12-04
  • 1970-01-01
  • 2020-08-06
  • 2012-06-06
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多