Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

createContext的使用的疑问 #4675

Closed
jiangbo0216 opened this issue Oct 24, 2019 · 8 comments
Closed

createContext的使用的疑问 #4675

jiangbo0216 opened this issue Oct 24, 2019 · 8 comments
Assignees

Comments

@jiangbo0216
Copy link

nanjingboy/taro-mobx-sample#8 (comment)

下面的原文

import { observable, action } from 'mobx'
import { createContext } from '@tarojs/taro';

// 这种写法无法使用
// class MenuStore {
//   isShowSeedBarn = false


//   toggleIsShowSeedBarn () {
//     this.isShowSeedBarn = !this.isShowSeedBarn
//   }
// }

// decorate(MenuStore, {
//   isShowSeedBarn: observable
// })

// 这种写法无法使用

// const MenuStore = observable({
//   isShowSeedBarn: false,


//   toggleIsShowSeedBarn () {
//     this.isShowSeedBarn = !this.isShowSeedBarn
//   }
// })
// export default createContext(MenuStore)




interface MenuStore {
  isShowSeedBarn: boolean 
}

class MenuStore {
  @observable isShowSeedBarn = false


  @action.bound
  toggleIsShowSeedBarn() {
    this.isShowSeedBarn = !this.isShowSeedBarn
  }
}

export default createContext(new MenuStore())

上面总共有三种写法,第一种和第二种无法使用,
环境如下:
$ taro info
👽 Taro v1.3.20

Taro CLI 1.3.20 environment info:
System:
OS: Windows 10
Binaries:
Node: 10.16.3 - ~\scoop\apps\nvm\current\nodejs\nodejs\node.EXE
Yarn: 1.19.1 - ~\scoop\apps\nvm\current\nodejs\nodejs\yarn.CMD
npm: 6.9.0 - ~\scoop\apps\nvm\current\nodejs\nodejs\npm.CMD

第一种写法借鉴了 https://codesandbox.io/s/3kmkj56qm?from-embed
第二种是原来脚手架的写法
第三种是这个仓库的写法,可用.
第一种和第二种错误提示为

thirdScriptError
Cannot read property 'isShowSeedBarn' of undefined; [Component] Event Handler Error @ components/menu#(anonymous)
TypeError: Cannot read property 'isShowSeedBarn' of undefined

不知道什么原因,请求帮助(●'◡'●)

@taro-bot
Copy link

taro-bot bot commented Oct 24, 2019

欢迎提交 Issue~

如果你提交的是 bug 报告,请务必遵循 Issue 模板的规范,尽量用简洁的语言描述你的问题,最好能提供一个稳定简单的复现。🙏🙏🙏

如果你的信息提供过于模糊或不足,或者已经其他 issue 已经存在相关内容,你的 issue 有可能会被关闭。

Good luck and happy coding~

@jiangbo0216
Copy link
Author

看起来这样子是可行的

class MenuStore {
  isShowSeedBarn = false


  toggleIsShowSeedBarn () {
    this.isShowSeedBarn = !this.isShowSeedBarn
  }
}

decorate(MenuStore, {
  isShowSeedBarn: observable,
  toggleIsShowSeedBarn: action.bound
})

但是这里的 https://codesandbox.io/s/3kmkj56qm?from-embed 代码为什么可以,难道是

export class Todos {
  todos = [
    { id: 1, text: 'Buy eggs', completed: true },
    { id: 2, text: 'Write a post', completed: false }
  ]

  get remainingTodos() {
    return this.todos.filter(t => !t.completed).length
  }

  toggleTodo = index => {
    this.todos[index].completed = !this.todos[index]
      .completed
  }
}

decorate(Todos, {
  todos: observable,
  remainingTodos: computed
})

get remainingTodos() {
return this.todos.filter(t => !t.completed).length
}
remainingTodos: computed 这个被修饰了的原因
image

@nanjingboy
Copy link
Member

@jiangbo0216 稍晚一点再帮你看下,今天有点忙。

@nanjingboy
Copy link
Member

nanjingboy commented Oct 25, 2019

@jiangbo0216 可以的啊:

store.js

import { observable, decorate } from 'mobx'
import { createContext } from '@tarojs/taro';

class MenuStore {
  isShowSeedBarn = false

  toggleIsShowSeedBarn () {
    this.isShowSeedBarn = !this.isShowSeedBarn
  }
}

decorate(MenuStore, {
  isShowSeedBarn: observable
})

export default createContext(new MenuStore())

index.jsx

import Taro, { useContext } from '@tarojs/taro'
import { View } from '@tarojs/components'
import { observer } from '@tarojs/mobx'
import Store from './store'
import './index.scss'

function Index() {
  const { isShowSeedBarn } = useContext(Store)

  return (
    <View>
      <View>{isShowSeedBarn ? 'true' : 'false'}</View>
    </View>
  )
}

export default observer(Index);

@nanjingboy
Copy link
Member

nanjingboy commented Oct 25, 2019

@jiangbo0216 你的问题是为什么调用 toggleIsShowSeedBarn 的时候找不到 isShowSeedBarn?如果这是你的疑问,不知道你的调用方式是否如下所示:

const { isShowSeedBarn, toggleIsShowSeedBarn } = useContext(Store);

return (
  <View>
    <View>{isShowSeedBarn ? 'true' : 'false'}</View>
    <Button onClick={toggleIsShowSeedBarn}>添加</Button>
  </View>
)

如果是这样的话,那是因为 JSthis 作用域问题,这样改造就可以了:

const store = useContext(Store);
const { isShowSeedBarn } = store;
return (
  <View>
    <View>{isShowSeedBarn ? 'true' : 'false'}</View>
    <Button onClick={() => store.toggleIsShowSeedBarn()}>添加</Button>
  </View>
)

你再仔细看下你给的 https://codesandbox.io/s/3kmkj56qm?from-embed 例子,它也是这样处理的。

@nanjingboy
Copy link
Member

nanjingboy commented Oct 25, 2019

@jiangbo0216 第二种写法同理

@jiangbo0216
Copy link
Author

你再仔细看下你给的 https://codesandbox.io/s/3kmkj56qm?from-embed 例子,它也是这样处理的。

是的,在使用解构获取 const { isShowSeedBarn, toggleIsShowSeedBarn } = useContext(Store);
的时候,this的指向发生了变化

@jiangbo0216
Copy link
Author

@jiangbo0216 第二种方法同理

感谢你的热心回复

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants