简体   繁体   English

React,Redux和Recompose:“调度不是函数”

[英]React, Redux and Recompose: “dispatch is not a function”

I've got a container/component (from Redux examples) complaining about " dispatch is not a function ". 我有一个容器/组件(来自Redux示例)抱怨“ 调度不是函数 ”。 I had this working before I added Recompose . 在添加Recompose之前,我已经完成了这项工作。 I think Recompose puts a wrapper around dispatch() , so I need to expose it somehow. 我认为Recompose将一个包装器放在dispatch()周围,​​因此我需要以某种方式公开它。 Maybe applyMiddleware will do the trick, but I don't know where to hook it up? 也许applyMiddleware可以解决问题,但我不知道在哪里连接它? What do I need to do? 我需要做什么?

Container: 容器:

const AddTodo = (props, dispatch) => {
  let input;
  const { classes } = props;
  return (
    <div>
      <form
        id="my-form-id"
        onSubmit={e => {
          e.preventDefault();
          if (!input.value.trim()) {
            return;
          }
          dispatch(addTodo(input.value));//<<<OFFENDING LINE
          input.value = "";
        }}
      >
        <TextField
          id="agentName"
          label="Agent Name"
          placeholder="Placeholder"
          form="my-form-id"
          inputRef={el => (input = el)}
          className={classes.textField}
          margin="normal"
        />
        <Button variant="extendedFab" type="submit" className={classes.button}>
          <AddIcon className={classes.addIcon} />
          New Todo
        </Button>
      </form>
    </div>
  );
};

export default compose(
  withStyles(styles),
  connect()
)(AddTodo);

Root index.js: 根index.js:

import React from "react";
import { render } from "react-dom";
import { createStore, applyMiddleware } from "redux";
import { Provider } from "react-redux";
import App from "./components/App";
import rootReducer from "./reducers";

const store = createStore(rootReducer);

render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);

There are two basic things to understand. 有两点要理解的基本知识。

1. When composing connect() Redux adds dispatch as a prop. 1.编写connect() Redux将派发添加为道具。

export default compose(
  withStyles(styles),
  connect() // <-- This adds dispatch to props.
)(AddTodo);

2. You should access props as a single object or destructure branches of the props object . 2.您应该将props作为单个对象进行访问,或将props对象的结构 props分支

This line is where the misunderstanding is happening. 这条线是误会发生的地方。

const AddTodo = (props, dispatch) => { // <-- dispatch is not an parameter, it exists at props.dispatch

To fix things using your existing pattern do this. 要使用现有模式修复问题,请执行此操作。

const AddTodo = (props) => {
  let input;
  const { classes, dispatch } = props;
  return (
  ...

Optionally you can destructure the props parameter directly. (可选)您可以直接分解props参数。

const AddTodo = ({ classes, dispatch }) => {
  let input;
  return (
  ...

With either approach the remaining code will work as expected. 无论采用哪种方法,其余代码都将按预期工作。

connect passes the dispatch as a prop to the connected component, you should destructure it from the props. connect将dispatch作为道具传递到已连接的组件,您应该将其从道具中解构。

const AddTodo = ({classes, dispatch}) => {
  let input;

  return (
    <div>
      <form
        id="my-form-id"
        onSubmit={e => {
          e.preventDefault();
          if (!input.value.trim()) {
            return;
          }
          dispatch(addTodo(input.value));
          input.value = "";
        }}
      >
        <TextField
          id="agentName"
          label="Agent Name"
          placeholder="Placeholder"
          form="my-form-id"
          inputRef={el => (input = el)}
          className={classes.textField}
          margin="normal"
        />
        <Button variant="extendedFab" type="submit" className={classes.button}>
          <AddIcon className={classes.addIcon} />
          New Todo
        </Button>
      </form>
    </div>
  );
};

export default compose(
  withStyles(styles),
  connect()
)(AddTodo);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM