mapDispatchToProps中的链接胖箭头使我出错

时间:2019-07-05 10:56:22

标签: javascript reactjs redux react-redux

  

错误:动作必须是普通对象。使用自定义中间件执行异步操作。

我正在尝试在var field = ((Microsoft.Office.Interop.Excel.PivotField)pvt.PivotFields((item as PropertyAggregateDescription).PropertyName)); field.Orientation = Microsoft.Office.Interop.Excel.XlPivotFieldOrientation.xlDataField; field.Function = Microsoft.Office.Interop.Excel.XlConsolidationFunction.xlSum; field.Calculation = Microsoft.Office.Interop.Excel.XlPivotFieldCalculation.xlDifferenceFrom; 中链接粗箭头功能,但似乎不起作用。

容器和动作创建者:

mapDispatchToProps

哑巴组件


// Actions Creator
const inputChange = (name: string) => (
  e: React.FormEvent<HTMLInputElement>
) => ({
  type: INPUT_CHANGE,
  name,
  value: e.currentTarget.value
});

// Dispatch
const mapDispatchToProps = {
  inputChange
};

// Connect
export default connect(
  mapStateToProps,
  mapDispatchToProps
)(SignUp);

也许这段代码的某些部分似乎有些奇怪,因为我删除了一些const SignUp = ({ inputChange }) => ( <input type="password" placeholder="Password" onChange={inputChange('password')} /> ); 以便不添加多余的毫无意义的代码。

无论如何,错误都来自types,使用单个粗箭头似乎没问题,但是当我开始链接它们时,我会收到此错误(即使它们返回了一个对象)。

3 个答案:

答案 0 :(得分:2)

由于提到的错误actions必须是普通对象,但是在链接函数时,实际上是在传递function(链上的下一个)而不是object

您遇到的问题是,除了实际的DOM事件之外,您还想传递一个额外的参数,例如input的名称,即:“ password”,“ user”等...

然后为什么不给input命名并在动作创建器函数中获取它(与使用value属性相同)。

您的表单可以如下所示:

const Form = ({ inputChange, form }) => (
<div>
  <input name="user" onChange={inputChange} type="text" value={form.user} />
  <input name="password" onChange={inputChange} type="password" value={form.password} />
</div>
);

const mapState = state => ({
  form: state
});

const mapDispatch = {
  inputChange
};

const ConnectedForm = connect(
  mapState,
  mapDispatch
)(Form);

在动作创建者内部:

const inputChange = ({ target }) => ({
  type: INPUT_CHANGE,
  payload: {
    value: target.value,
    inputName: target.name
  }
});

减速器可以处理它,如下所示:

const reducer = (state = {user: '', password: ''}, action) => {
  switch (action.type) {
    case INPUT_CHANGE: {
      const { inputName, value } = action.payload;
      return {
        ...state,
        [inputName]: value
      };
    }

    default:
      return state;
  }
};

运行示例:

// mimic imports
const { createStore } = Redux;
const { Provider, connect } = ReactRedux;


const INPUT_CHANGE = "INPUT_CHANGE";
const reducer = (state = {user: '', password: ''}, action) => {
  switch (action.type) {
    case INPUT_CHANGE: {
      const { inputName, value } = action.payload;
      const nextState = {
        ...state,
        [inputName]: value
      };
      console.clear();
      console.log('store', nextState);
      return nextState;
    }

    default:
      return state;
  }
};

const inputChange = ({ target }) => ({
  type: INPUT_CHANGE,
  payload: {
    value: target.value,
    inputName: target.name
  }
});

const store = createStore(reducer);

const Form = ({ inputChange, form }) => (
<div>
  <input name="user" onChange={inputChange} type="text" value={form.user} />
  <input name="password" onChange={inputChange} type="password" value={form.password} />
</div>
);

const mapState = state => ({
  form: state
});

const mapDispatch = {
  inputChange
};

const ConnectedForm = connect(
  mapState,
  mapDispatch
)(Form);

class App extends React.Component {
  render() {
    return (
      <div>
        <ConnectedForm />
      </div>
    );
  }
}

const root = (
  <Provider store={store}>
    <App />
  </Provider>
);

const rootElement = document.getElementById("root");
ReactDOM.render(root, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.1/redux.min.js
"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/4.4.10/react-redux.min.js"></script>
<div id="root"/>

答案 1 :(得分:1)

尝试使用以下语法。

const mapDispatchToProps = dispatch => {
  return {
    inputChange: () => {
      dispatch(inputChange("value"))
    }
  };
};

答案 2 :(得分:1)

您正在从操作中返回不可接受的功能。没有中间件的调度只接受平面对象,而不接受函数。

要么使用Thunk或saga之类的中间件,要么更改逻辑以返回对象,但不能像下面那样起作用

动作

// Actions Creator
const inputChange = (name: string, value: string) => ({
    type: INPUT_CHANGE,
    name,
    value
});

组件

const SignUp = ({ inputChange }) => (
    <input
        type="password"
        placeholder="Password"
        onChange={(e) => inputChange('password', e.target.value)}
    />
);