Home Java Is it possible without Redux?

Is it possible without Redux?

by admin

There are plenty of positions today that require react/redux. React is great, no question about it. The question for Redux is whether it is possible without it. If you google a little bit, you’ll find a good one. Habra article where the author asks the same question. In the article, with a simple example (todoList), the this.updateViews() method is called too often (seven to eight times) and it seems like it could be made simpler.
The basic idea here is observable models, react is responsible for observable, it’s just a matter of creating models.
Before creating the model, a few words about the client’s design (architecture) :
index – raw data
history — array[model]
observer — model
view — errors, focus, flags
index.jsx is the program’s entry point for the user’s screen. Index draws all components with default data, makes asynchronous requests, redraws components with new data.

// index.jsx<History><Observer><HeaderView /><MainView /></Observer></History>

Observer.jsx is responsible for synchronizing the model for multiple views. For example, Petya fills out a form for an offerer and sees a real-time preview in the page header. Observer stores the model object, giving the child components api: onModelChange(field, value).
History.jsx is a stack of model objects where api: commit and rollback.
Model.js is what the user can enter by hand – that is, the most valuable. There is no need to store other data in the model. Model is not a react component, but a regular js class.

class Model {constructor(other = {}) {} // copy constructor (and default too)isEqual(other) {} // operator ==less(other) {} // operator<swap(other) {}hash() {}fieldNameConstrains() {} //see below please}

The copy constructor is at least needed for History. The isEqual method is for popup-unsaved-changes (which is much more convenient than the flag in state). FieldNameConstrains method – for dependent fields.
Roughly speaking, if there are dependent fields, they should be changed all together.

class Model {// constrains// distance <== velocity * timevelocityConstrains(newVelocity) {this.velocity = newVelocity;this.distance = this.velocity * this.time;}timeConstrains(newTime) { … }distanceConstrains(newDistance) {this.distance = newDistance;this.time = this.distance / this.velocity;}}

From personal experience, something like model.field.onchange doesn’t work because sometimes you need to call the copy constructor and onchange events aren’t needed at all.
View.jsx

class View extends React.Component {state = {errors: {}, focus: {}, …}render() {…<inputvalue={this.props.model.title}onChange={e => this.props.onModelChange(‘title’, e.target.value)} />…}}

Validation. Validation doesn’t have to be done in the model. It should be done in the view (don’t forget that the view is the user’s screen and that the screen may not show the whole model). Validators are a set of predicates. There are only two algorithms for validation: 1) find all errors in the form or 2) find the first error. For example,

class View extends React.Component {onClickSaveButton() {const mapper = {title: () => model.title.length !maxLenValidator(model.title, 25), price: () => !(model.price % 40 == 0), url: () => !urlValidator(model.url), …}const errors = map(mapper, (validator, key) => {return validator() ? key : undefined;}).filter(Boolean);}// validators are easy to test and easy to reuse

Access rights. The main thing here is to hold back and not use inheritance. The idea is that the model contains all fields and we truncate fields for roles. That is whitelist, other fields in the model remain by default. For validation we add one step – we make projection of validation object (it’s also mapper, see above), that is we validate only required fields.
About Production. This approach has been spinning in production for a year now – it’s an interface for creating ad campaigns, including banners. Forms of varying complexity – from a single model per screen, to multiple models of different types. I might add here that the backend likes to send nested structures, you need to feel free to store only flat structures in the view.
About the isEqual model method. Somewhere in utils.js there will be methods isEqual and isEqualArray:

function isEqual(left, right) {return left.isEqual(right);}isEqualArray(v1, v2) {if (v1.length !== v2.length) { return false }for (var k = 0; k != v1.length; k++) {if (!isEqual(v1[k], v2[k])) { return false; }}return true;}

You should try not to make models nested. Don’t forget that a model is user data, not a data structure.
References :
Raz
Two

You may also like