“调度”是否必须称为“调度”,还是您可以直接调用调度而不标记它?

问题描述

我一直在 redux调用 dispatch ,但我从未使用过“dispatch”这个词。我刚刚调用了这样的函数

import React from 'react';
import {connect} from 'react-redux';

class RecipeList extends React.Component{
    componentDidMount(){
        console.log(this.props)
    }
    render(){
        return(
            <div>
                <form>
                    <input />
                    <button>SEARCH</button>
                </form>
            </div>
        )
    }
}

const mapStatetoProps = (state)=>{
    return {recipe_list: state}
}
const testing = ()=>{
    return {
        type:'TEST'
    }
}

export default connect(mapStatetoProps,{testing: testing})(RecipeList);

可以接受吗?它有效。

解决方法

mapDispatchToProps 参数可以是 undefinedobjectfunction。如果未定义,则 react-redux 会将 dispatch 添加到 props。

以下是 3 个示例,说明如何将其与 undefined、函数或对象一起使用,以及使用 react-redux hooks 的示例。我建议使用钩子,因为这是 React 的发展方向(而不是像 connect 这样的 HOC)。

const {
  Provider,connect,useSelector,useDispatch,} = ReactRedux;
const { createStore,applyMiddleware,compose } = Redux;

const initialState = {
  items: [{ id: 1,name: 'item 1' }],};
//action types
const DELETE = 'DELETE';
//action creators
const deleteItem = (id) => ({
  type: DELETE,payload: id,});
const reducer = (state,{ type,payload }) => {
  console.log('action:',type,'payload:',payload);
  return state;
};
//creating store with redux dev tools
const composeEnhancers =
  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
  reducer,initialState,composeEnhancers(
    applyMiddleware(() => (next) => (action) =>
      next(action)
    )
  )
);
//you should use reselect here but for simplicity I didn't
const mapStateToProps = (state,{ id }) => ({
  item: state.items.find((item) => item.id === id),});
//if mapDispatchToProps is undefined then react-redux
//  will add dispatch to props,here is how you can delete
const ItemMapDispatchUndefined = ({ item,dispatch }) => (
  <button onClick={() => dispatch(deleteItem(item.id))}>
    undefined - delete {item.name}
  </button>
);
const ConnectedDispatchUndefined = connect(mapStateToProps)(
  ItemMapDispatchUndefined
);
//if mapDispatchToProps is an object then react-redux
//  will take the properties of that object and if a
//  property is a functoin it will wrap that function
//  in a new function that will automatically dispatch
//  the return value when that function is called
const ItemMapDispatchObject = ({ item,deleteItem }) => (
  // no dispatch needed but still need to pass id to deleteItem
  <button onClick={() => deleteItem(item.id)}>
    object - delete {item.name}
  </button>
);
const ConnectedDispatchObject = connect(mapStateToProps,{
  deleteItem,})(ItemMapDispatchObject);
//if mapDispatchToProps is a function then that function needs
//  to return an object where each property of that object is a
//  function that will dispatch an action. These properties
//  will be added to component props by react-redux
const ItemMapDispatchFunction = ({ item,deleteItem }) => (
  // no dispatch needed and no id needs to be passed
  <button onClick={deleteItem}>
    function - delete {item.name}
  </button>
);
const ConnectedItem3 = connect(
  mapStateToProps,(dispatch,{ id }) => ({
    deleteItem: () => dispatch(deleteItem(id)),})
)(ItemMapDispatchFunction);
//using hooks (not using connect at all)
const Hooks = ({ id }) => {
  //should use reselect but for simplicity not used
  const item = useSelector((state) =>
    state.items.find((item) => item.id === id)
  );
  const dispatch = useDispatch();
  return (
    <button onClick={() => dispatch(deleteItem(item.id))}>
      hooks - delete {item.name}
    </button>
  );
};

const App = () => {
  return (
    <div>
      <ConnectedDispatchUndefined id={1} />
      <ConnectedDispatchObject id={1} />
      <ConnectedItem3 id={1} />
      <Hooks id={1} />
    </div>
  );
};

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script>
<div id="root"></div>