remix-project
remix-project copied to clipboard
Could remix consider to use redux and redux-saga to manage state?
The state of remix is too complicated for useReducer
to handle it. Redux + Redux-Saga is a better solution, which I'v already tried in the new LearnEth plugin.
Check this https://github.com/drafish/remix-project/blob/learneth/apps/learneth/src/redux/models/workshop.ts
It's conciser than useReducer
.
Could remix consider this way? I can help if you like my idea. @yann300 @ryestew
@ioedeveloper @joeizang could you give your opinion on this?
I don't think redux and redux saga holds any benefit here. Most of the react world are moving away from redux to things like zustand or jotai or even using async state managers like @tanstack/react-query. So I think using redux in learnEth isn't the way to go in my opinion.
Additionally, using redux will require rethinking the architecture of our current solution. We aren't at the point of rethinking this solution yet, I think. Here is my argument: https://redux.js.org/faq/general#when-should-i-use-redux @yann300 @ryestew @ioedeveloper I think we should discuss this internally as this issue shines a light on other outstanding issues.
Sorry for the late response. Got a little busy recently. I'v been thinking about how to convince you guys to use redux and redux saga.
Here is the reason I got from https://redux.js.org/faq/general#when-should-i-use-redux
Redux is most useful in cases when:
- You have large amounts of application state that are needed in many places in the app
- The app state is updated frequently
- The logic to update that state may be complex
- The app has a medium or large-sized codebase, and might be worked on by many people
- You need to see how that state is being updated over time
I think it's talking about remix.
Besides, what I'm suggesting is not just redux and redux saga, also a little trick I learned from dva.js.
I wraped redux and redux saga, and put every thing in model. Here is a model example.
{
namespace: 'instance',
state: {
name: '',
address: '',
network: '',
abi: [],
defaultAbi: [],
},
reducers: {
save(state, {payload}) {
return {...state, ...payload}
},
},
effects: {
*deploy({payload}, {select}) {
try {
yield surgeClient.login({
user: payload.email,
password: payload.password,
})
} catch (error) {
return {code: 'ERROR', error: error.message}
}
const {defaultAbi, ...instance} = yield select((state) => state.instance)
const files: Record<string, string> = {'dir/instance.json': JSON.stringify(instance), 'dir/index.html': template}
try {
yield surgeClient.publish({
files,
domain: `${payload.subdomain}.surge.sh`,
onProgress: ({id, progress, file}: {id: string; progress: number; file: string}) => {
console.log({id, progress, file})
},
onTick: (tick: string) => {},
})
} catch (error) {
return {code: 'ERROR', error: 'this domain belongs to someone else'}
}
return {code: 'SUCCESS', error: ''}
},
},
}
The app state is splited by namespace, and every namespace has its own state. You can put the sync actions in reducers, and async actions in effects.
When you need to dispatch an action, dispatch it like this
const dispatch = useAppDispatch()
dispatch({
type: 'instance/deploy',
payload: formVal,
callback: (state) => {
setDeployState(state)
},
})
When you need to use any state, use it like this
const abi = useAppSelector(state => state.instance.abi)
It's easy to manage the state and define actions this way. And you can always dispatch any actions and use any state in anywhere you want.
Remix is consist of plugins. Each plugin has its own state, and will call other plugins and be called. It's a good choice when the plugin call involves iframe. But it's a waste when the call is just between native plugins. You have to emit an event in plugin A, and listen on the event in plugin B, when B is using the state of A.
The communication between native plugins shouldn't be so hard. I mean they share the same context, there should be a much easier and straightforward way. That's what I'm proposing. We can define a model for each plugin, and replace plugin call with dispatch.
And you don't need to worry about the architecture of your current solution. It's compatible. You don't have to replace all useReducer with redux at once. We can start from small plugins, then the middle ones, then the large ones.
If you don't want to try redux immediately, at least try it in iframe plugins. I'v already developed two iframe plugins, which is learneth and dapp-draft. Here is the code of dapp-draft.
https://github.com/drafish/remix-project/tree/dapp-draft-bk/apps/dapp-draft/src
Please read my code, see how I manage state, define and dispatch actions, and compare with your way. I still think my way is much easier and straightforward.
@joeizang @yann300 @ioedeveloper @LianaHus @bunsenstraat
As a matter of policy, agreed by the team, our way of handling complex state in react components is useReducer and useContext. We will NOT be using Redux and Redux Saga anywhere in the project for now. We discussed this internally and unanimously agreed not to go with Redux and Redux Saga.
@yann300 @bunsenstraat @LianaHus @ioedeveloper I would suggest we ask for a pr to remove redux and redux saga in the LearnEth plugin. And please I humbly ask that you all weigh in on this matter.
Your suggestions are noble @drafish but
even core react team members at meta cringe from redux. Even the co-creator of Redux admits that redux was a bad idea.
Unless we have a change of heart, the team's position is my position on this matter.
As a matter of policy, agreed by the team, our way of handling complex state in react components is useReducer and useContext. We will NOT be using Redux and Redux Saga anywhere in the project for now. We discussed this internally and unanimously agreed not to go with Redux and Redux Saga.
@yann300 @bunsenstraat @LianaHus @ioedeveloper I would suggest we ask for a pr to remove redux and redux saga in the LearnEth plugin. And please I humbly ask that you all weigh in on this matter.
Your suggestions are noble @drafish but
even core react team members at meta cringe from redux. Even the co-creator of Redux admits that redux was a bad idea.
Unless we have a change of heart, the team's position is my position on this matter.
if the code is in our codebase it should be removed. the style part also not done there. @yann300 @ryestew