{"id":625,"hash":"f2e7cc3fa3deb171a5cc4e83a34dc4ef714d6c7edf8174776b17b04092dd3045","pattern":"Avoid no-shadow eslint error with mapDispatchToProps","full_message":"I have the following component that triggers a no-shadow ESlint error on the FilterButton props.\n\nimport { setFilter } from '../actions/filter';\n\nfunction FilterButton({ setFilter }) {\n  return (\n    <button onClick={setFilter}>Click</button>\n  );\n}\n\nexport default connect(null, { setFilter })(FilterButton);\n\nHow can I avoid the warning while keeping both the concise syntax of mapDispatchToProps and the ESlint rule?\n\nI know I can add a comment to suppress the warning but doing it for every components seems redundant and tedious.","ecosystem":"npm","package_name":"reactjs","package_version":null,"solution":"There are four options here:\n\n1. Disable the rule.\n\nWhy?\n\nIt's the easiest way to avoid the ESLint error.\n\nWhy Not?\n\nThe no-shadow rule helps to prevent a very common bug when using react-redux. That is, attempting to invoke the raw, unconnected action (which does not automatically get dispatched).\n\nIn other words, if you were not using destructuring and grabbing the action from props, setFilter() would not dispatch the action (because you'd be invoking the imported action directly, as opposed to invoking the connected action through props via props.setFilter(), which react-redux automatically dispatches for you).\n\nBy cleaning up variable shadowing, you and/or your IDE are more likely to pick up on the error.\n\nHow?\n\nAdding a eslintConfig property to your package.json file is one way to do this.\n\n\"eslintConfig\": {\n    \"rules\": {\n      \"no-shadow\": \"off\",\n    }\n  }\n\n2. Reassign the variable when passing it into connect().\n\nWhy?\n\nYou benefit from the safety of the no-shadow rule, and, if you choose to adhere to a naming convention, it's very explicit.\n\nWhy Not?\n\nIt introduces boilerplate.\n\nIf you do not use a naming convention, you now have to come up with alternate names (that still make sense) for every action. And chances are that the same actions will be named differently across components, making it harder to become familiar with the actions themselves.\n\nIf you do use a naming convention, names become long and repetitive.\n\nHow?\n\nWithout naming convention:\n\nimport { setFilter } from '../actions/filter';\n\nfunction FilterButton({ filter }) {\n  return (\n    <button onClick={filter}>Click</button>\n  );\n}\n\nexport default connect(null, { filter: setFilter })(FilterButton);\n\nWith naming convention:\n\nimport { setFilter, clearFilter } from '../actions/filter';\n\nfunction FilterButton({ setFilterConnect, clearFilterConnect }) {\n  return (\n    <button onClick={setFilterConnect} onBlur={clearFilterConnect}>Click</button>\n  );\n}\n\nexport default connect(null, {\n  setFilterConnect: setFilter,\n  clearFilterConnect: clearFilter,\n})(FilterButton);\n\n3. Don't destructure actions off of props.\n\nWhy?\n\nBy explicitly using the method off of the props object, you don't need to worry about shadowing to begin with.\n\nWhy Not?\n\nPrepending all of your actions with props/this.props is repetitive (and inconsistent if you're destructuring all of your other non-action props).\n\nHow? \n\nimport { setFilter } from '../actions/filter';\n\nfunction FilterButton(props) {\n  return (\n    <button onClick={props.setFilter}>Click</button>\n  );\n}\n\nexport default connect(null, { setFilter })(FilterButton);\n\n4. Import the entire module.\n\nWhy?\n\nIt's concise.\n\nWhy Not?\n\nOther developers (or your future self) may have trouble understanding what's going on. And depending on the style guide you're following, you might be breaking the no-wildcard-imports rule.\n\nHow?\n\nIf you're simply passing in action creators from one module:\n\nimport * as actions from '../actions/filter';\n\nfunction FilterButton({ setFilter }) {\n  return (\n    <button onClick={setFilter}>Click</button>\n  );\n}\n\nexport default connect(null, actions)(FilterButton);\n\nIf you're passing in multiple modules, use object destructuring with rest syntax:\n\nimport * as filterActions from '../actions/filter';\nimport * as otherActions from '../actions/other';\n\n// all exported actions from the two imported files are now available as props\nfunction FilterButton({ setFilter, clearFilter, setOther, clearOther }) {\n  return (\n    <button onClick={setFilter}>Click</button>\n  );\n}\n\nexport default connect(null, { ...filterActions, ...otherActions })(FilterButton);\n\nAnd since you mentioned a preference for ES6's concise syntax in the comments, might as well throw in the arrow function with an implicit return:\n\nimport * as actions from '../actions/filter';\n\nconst FilterButton = ({ setFilter }) => <button onClick={setFilter}>Click</button>;\n\nexport default connect(null, actions)(FilterButton);","confidence":0.95,"source":"stackoverflow","source_url":"https://stackoverflow.com/questions/37682705/avoid-no-shadow-eslint-error-with-mapdispatchtoprops","votes":94,"created_at":"2026-04-19T04:51:24.129127+00:00","updated_at":"2026-04-19T04:51:24.129127+00:00"}