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

Store是否支持自定义selector #4267

Open
4n9le-bot opened this issue Apr 26, 2021 · 3 comments
Open

Store是否支持自定义selector #4267

4n9le-bot opened this issue Apr 26, 2021 · 3 comments
Assignees

Comments

@4n9le-bot
Copy link

  1. models/project.js
export default {
  state: {
    projects: [
    { id: 1, name: 'ProjectA' },
    { id: 2, name: 'ProjectB' },
    { id: 3, name: 'ProjectC' },
    ],
    current: 1,
  },
}
  1. selectors/index.js
export const selectCurrentProject = (state) => state.projects.find(state.current)
  1. Usage in component
const [currentProject, projectDispatchers] = store.useModel('project', selectCurrentProject)
@luhc228
Copy link
Collaborator

luhc228 commented Apr 27, 2021

你要实现什么样的效果呢?

目前看来传入 selectCurrentProject 函数只是想获取到对应的 project。和拿到 state 后再调用 selectCurrentProject 函数没有太大区别:

const [projectState, projectDispatchers] = store.useModel('project');

const currentPRoject = selectCurrentProject(projectState);

@4n9le-bot
Copy link
Author

4n9le-bot commented Apr 29, 2021

感谢回复!

之前项目里了用了reselector

Reselect provides a function createSelector for creating memoized selectors. createSelector takes an array of input-selectors and a transform function as its arguments. If the Redux state tree is mutated in a way that causes the value of an input-selector to change, the selector will call its transform function with the values of the input-selectors as arguments and return the result. If the values of the input-selectors are the same as the previous call to the selector, it will return the previously computed value instead of calling the transform function.

例子:

import { createSelector } from 'reselect'

const shopItemsSelector = state => state.shop.items
const taxPercentSelector = state => state.shop.taxPercent
const subtotalSelector = createSelector(
  shopItemsSelector,
  items => items.reduce((subtotal, item) => subtotal + item.value, 0)
)

const taxSelector = createSelector(
  subtotalSelector,
  taxPercentSelector,
  (subtotal, taxPercent) => subtotal * (taxPercent / 100)
)

const totalSelector = createSelector(
  subtotalSelector,
  taxSelector,
  (subtotal, tax) => ({ total: subtotal + tax })
)

const exampleState = {
  shop: {
    taxPercent: 8,
    items: [
      { name: 'apple', value: 1.20 },
      { name: 'orange', value: 0.95 },
    ]
  }
}

console.log(subtotalSelector(exampleState)) // 2.15
console.log(taxSelector(exampleState))      // 0.172
console.log(totalSelector(exampleState))    // { total: 2.322 }

而且原生的react-redux里有useSelector
const result: any = useSelector(selector: Function, equalityFn?: Function)

比如有个的组件,只显示当前project的title,用useSelector(selectTitleOfCurrentProject)话,不需要把过多的信息(整个projectState)暴露给该组件。

@luhc228
Copy link
Collaborator

luhc228 commented Apr 29, 2021

嗯嗯。目前 @ice/store 并没有相关 API 支持类似 reselector 的功能,会考虑在后面支持上。

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

No branches or pull requests

3 participants