Redux architecture for a text editor: working with related states

I am building an application with React / Redux that is somewhat similar to a text editor. This is not a text editor, but the same general paradigm. There is a cursor to place new items. Items can be added, selected, deleted, etc.

I'm struggling to structure my gearboxes in a way that matches the spirit of redux. I have separate state slices representing the state of the selection, the text itself, the state of the cursor, and other settings. I think the redux approach will have reducers for each of these state slices, independently changing state in response to the action.

However, in a text editor, these sections of the state are much more complicated than at first glance. When you press a key, sometimes a letter is added at the cursor location, and the cursor moves forward. However, if text is selected, the selected text will be deleted first. If you are in insert mode, the text on the right will be consumed. Or, perhaps the modifier key does not work, and the text is not added at all.

In other words, different sections of the state are very connected, and what happens in one depends on the current state of the others.

I read the “Beyond Combine Reducers” section of the Redux manual and know how to share the state between the slice reducers, but this seems inelegant if the end result passes all the state to each slice reducer. Another thing that I do not like about his approach is that each gearbox will have to look at the general condition and independently come to the same conclusion about what should be its correct answer to a specific action. Is this what I should do, or should I somehow structure my condition?

An alternative to a single centralized reducer indicating the cursor, selection state, content, etc., how to mutate is easier conceptually, but does not seem to scale very well.

I also read that many times the bound state is a sign that your state is not minimal and that you should restructure and use memoized selectors. However, this does not seem to be the case. The cursor position is not inferred from the text and is not a selection state.

Finally, I also looked at Thunk middleware, as this is what I saw offered for handling several / more complex actions. I do not dare, because it seems that it is more intended for asynchronous sending, and this is not so.

I would like to understand the right approach for developing this type of application, which is most consistent with the "redux" design pattern and understand any trade-offs that may exist if there are several ways forward.

+5
source share
2 answers

I wrote that “Structuring gearboxes” in the doc section, it’s so nice to see people at least read it and find it useful :)

You are right that the idiomatic approach to Redux reducer logic is small reducer functions organized by a state cut, independently responding to the same actions. However, this is not a fixed requirement, and there are certain points when it makes sense to consolidate part of the logic in one place.

It’s a little difficult to give absolute concrete advice without seeing what your state structure is and what kind of problems you are trying to solve, but in general, you should freely structure your state and logic of the gearbox, whatever way makes the most sense for your application. If it’s better to work with some logic in a more centralized reducer function, which immediately updates several nested parts of the state, go behind it!

Like a couple of other observations:

In the Redux Frequently Asked Questions question about “sharing gears,” one way is to add more information to the submitted action. For example, instead of sending {type : "KEYSTROKE", key : "A"} you can send {type : "KEYSTROKE", key : "A", cursorPos : 12345, ctrl : true, alt : false} .

In addition, although thunks are a good place for basic asynchronous logic, they are also useful for complex synchronous logic, including checking the current state of the application. I have an essence that demonstrates some common use cases for thunk .

Lemma send a couple more resources that can help you:

(As an additional note, I am also currently working on a blog post that will discuss what specific technical limitations Redux requires and why, as well as how you are “intended” to use Redux, and how you can use Redux. It will take a while to finish it, but check out my blog if you're interested.

Finally, if you want to continue the discussion, the Reactiflux chat channels on Discord are a great place to chat, research, and study. The invitation link is at https://www.reactiflux.com . Please feel free to ask questions - I’m usually there in the evenings in the USA, but there are always a lot of people chatting to discuss things.

+5
source

You seem to be doing a huge task; you may already know this, but creating a text editor from scratch is no easy task.

Did you rate using existing software?

I recently successfully used the super powerful Codemirror and integrated it with the React.js app. Codemirror already manages the concept of document state very well.

It means:

  • Codemirror instance fully controls the editor (AKA: document)
  • The responsive environment attaches to the document through callbacks and events.

If Codemirror does not meet your needs, look at its code and internals description.

0
source

Source: https://habr.com/ru/post/1267112/


All Articles