为什么React函数组件无需显式声明即可使用任意prop,如MST示例的store?
问题1:store的定义位置
你贴出的是官方示例中UI渲染相关的代码片段,store的实例化逻辑在同文件的前置代码中,完整流程如下:
- 先使用MST的
types.model定义Todo节点模型、根Store模型,给根Store挂载对应的业务方法(比如示例里用到的addTodo) - 调用根Store模型的
.create()方法完成实例化,赋值给store变量,伪代码参考:
// 示例前置代码逻辑 import { types } from "mobx-state-tree" const Todo = types.model({ id: types.identifier, name: types.string, done: types.boolean }).actions(self => ({ toggle() { self.done = !self.done }, setName(name) { self.name = name } })) const RootStore = types.model({ todos: types.map(Todo) }).actions(self => ({ addTodo(id, name) { self.todos.set(id, Todo.create({ id, name, done: false })) } })) // 此处就是你用到的store变量的定义位置 const store = RootStore.create({ todos: {} })
问题2:store={store}的写法说明
这是JSX的标准Prop传递语法,不存在特殊规则:
- 等号左侧的
store是你传递给App组件的Prop的自定义名称 - 等号右侧大括号里的
store是你前面实例化得到的store变量本身
你提到的“prop={store}”是错误的理解,React的Prop名称完全由开发者自定义,不需要固定叫prop。如果Prop名称和你要传递的变量名完全一致,还可以用JSX简写语法:<App {...{store}} />,效果和store={store}完全相同。
问题3:修改Prop名称报错的原因
你在App组件的实现逻辑中,写死了从props.store读取根Store数据:
// 组件内部硬编码了读取props.store <button onClick={e => props.store.addTodo(randomId(), "New Task")}> {values(props.store.todos).map(todo => (...))}
如果你传递Prop的时候把名称改成abcxyz={store},那么App组件收到的props对象中就不存在store属性,只有abcxyz属性,props.store的取值就是undefined,再尝试读取undefined.todos自然就会抛出你遇到的报错。
如果要修改传递的Prop名称,需要同步修改组件内所有读取store的逻辑,把props.store全部替换为props.abcxyz即可正常运行。
内容的提问来源于stack exchange,提问作者Lê Quốc Khánh
相关产品推荐
相关产品推荐

