如何避免向下传递回调?
如何避免向下传递回调?
React
我们已经发现大部分人并不喜欢在组件树的每一层手动传递回调。尽管这种写法更明确,但这给人感觉像错综复杂的管道工程一样麻烦。
在大型的组件树中,我们推荐的替代方案是通过 context 用 useReducer 往下传一个 dispatch
函数:
const TodosDispatch = React.createContext(null); function TodosApp() { // 提示:`dispatch` 不会在重新渲染之间变化 const [todos, dispatch] = useReducer(todosReducer); return ( <TodosDispatch.Provider value={dispatch}> <DeepTree todos={todos} /> </TodosDispatch.Provider> ); }
TodosApp
内部组件树里的任何子节点都可以使用 dispatch
函数来向上传递 actions 到 TodosApp
:
function DeepChild(props) { // 如果我们想要执行一个 action,我们可以从 context 中获取 dispatch。 const dispatch = useContext(TodosDispatch); function handleClick() { dispatch({ type: 'add', text: 'hello' }); } return ( <button onClick={handleClick}>Add todo</button> ); }
总而言之,从维护的角度来这样看更加方便(不用不断转发回调),同时也避免了回调的问题。像这样向下传递 dispatch
是处理深度更新的推荐模式。
注意,你依然可以选择是要把应用的 state 作为 props 向下传递(更显明确)还是作为作为 context(对很深的更新而言更加方便)。如果你也使用 context 来向下传递 state,请使用两种不同的 context 类型 —— dispatch
context 永远不会变,因此组件通过读取它就不需要重新渲染了,除非它们还需要应用的 state。
Vue
包含了父作用域中的 (不含 .native
修饰器的) v-on
事件监听器。它可以通过 v-on="$listeners"
传入内部组件——在创建更高层次的组件时非常有用,如果父组件中有很多事件。
<div> <child @change="handleChange">child</child> <p>父组件</p> </div>
那么内部组件可以通过 v-on="$listeners"
往下传递。
<div> <son v-on="$listeners">child</son> <p>内部组件</p> </div>
在下层组件 son
可以通过 $listeners
调用上层传递的事件。
methods: { change (index) { this.$listeners.change(index) } }
通常是通过 $emit
进行派发,但是如果有多层级嵌套的组件,每层都要派发事件,这样显得额外麻烦,而通过 $listener
显然变得简单多了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论