byte-fe / react-model

The next generation state management library for React
235 stars 22 forks source link

[RFC] Effect just belong to store for react-model v4 #185

Open EzrealPrince opened 2 years ago

EzrealPrince commented 2 years ago

Sometimes we want to watch a store state and do some effects

like this, by easy-peasy https://easy-peasy.vercel.app/docs/api/effect-on.html

export default createStore({
  items: [],
  saving: false,
  setSaving: action((state, payload) => {
    state.saving = payload;
  }),
  addItems: action((state, payload) => {
    state.items.push(payload);
  }),
  stateChange: unstable_effectOn(
    [(state) => state.items],
    async (actions, change) => {
      const [items] = change.current;
      actions.setSaving(true);
      await todosService.save(items);
      actions.setSaving(false);
    }
  )
});

in the react-model v4, we usually write it like this

export const { useStore } = createStore(() => {
  const [todoItems, setTodoItems] = useModel<string[]>([])
  const [saving, setSaving] = useModel<boolean>(false)

  const addItems = useCallback((item) => setTodoItems(todoItems => todoItems.push(item)), [])

  //  it will register repeatedly
  //  so may be provide a new store effect hook just execute once
  useEffect(() => {
    setSaving(true);
    await todosService.save(todoItems);
    setSaving(false);
  }, [todoItems])

  return {
    todoItems,
    saving,
    addItems
  }
})
catee commented 1 year ago

any update?

catee commented 1 year ago

@EzrealPrince It works for me. But I don't think it's the right way for solving this problem.

import { useModel, createStore } from 'react-model'

import axios from 'axios'

let needRequest = true

const useStore = () => {
  const [options, setOptions] = useModel({})

  if (needRequest) {
    axios(url, { data: {} }).then((data) =>
      setOptions(data)
    )
  }

  needRequest = false

  return options
}

// Model Register
export const { useStore: useOptions } = createStore(useStore)

Looking forward to @ArrayZoneYour 's reply ^_^