📜 ⬆️ ⬇️

The solution to the absence of prevProps in getDerivedStateFromProps

Hello friends!


So, the React developers decided to make our work with their library more linear, to send, so to speak, negligent people on the path of the least chance to make a mistake and write bad code, which, in my opinion, is our inalienable right and way to improve and invent. We are talking about all the favorite methods of componentWillReceiveProps and others from the same series; they will no longer be there, but we will be given an alternative in the form of the static method getDerivedStateFromProps. Personally, he reminds me of a dark room where things are lying, and they need to be found, but nothing is visible.


Developers in their responses to angry comments of users of the React write they say: Well, we will not give you prevProps, it is impossible, think up something, there is no prevProps, well, you stick there, just cache them in a state, in general they suggest that we make a small crutch in our new good code. Of course, this is all easy, you can understand and forgive, but now I was annoyed by the fact that now I don’t have this context, my room was bricked up, nothing could be seen from it, I couldn’t even hear the neighbors, so I decided to write something for myself It will hide all crutches and my code will look albeit strange, but boneless (is it boneless?).


In general, I need to implement prevProps into the component state, I still want everything to look as usual, and also it’s impossible to live without the magic this in static getDerivedStateFromProps (here is a fool!). Two days of torment and self-improvement and everything is ready, I gave birth to a mouse.


Installation


npm install --save state-master 

Using


Just write the same getDerivedStateFromProps and componentDidUpdate, but already modified.
We wrap our component in "withStateMaster", we transfer there the list of "props", which changes need to be monitored


 import {Component} from 'react' import {withStateMaster, registerContext, unregisterContext} from 'state-master'; //  "",     const PROP_LIST = ['width', 'height', 'bgColor', 'fontSize', 'autoSize']; //   ,     const PROP_LIST = 'value'; //     const INITIAL_STATE = { width: 1000, height: 500 }; class ContainerComponent extends Component { static displayName = 'Container'; static getDerivedStateFromProps(data) { const { nextProps, prevProps, state, isInitial, changed, changedProps, isChanged, add, addIfChanged, isChangedAny, addIfChangedAny, isChangedAll, call, get } = data; //      ,   ,      PROPS_LIST //   ,       if (isInitial) { //   "name"    "value"     add('name', value); //   "name"       add('name'); } // changedProps  ,       if (changedProps.indexOf('value') !== -1) { add('value'); } //  true   prop -  if (isChanged('autoSize')) { add('autoSize'); } //  true   prop     (  true) if (isChanged('autoSize', true)) { add('autoSize', true); } // changed  true,     -  if (changed) { add('somethingChanged', true); } //  true,     -  //   ,     if (isChangedAny()) { add('somethingChanged', true); } //  true,      -  if (isChangedAny('bgColor', 'fontSize', ...)) { const {bgColor, fontSize} = nextProps; add('style', {bgColor, fontSize}); } //  true,      PROPS_LIST -  if (isChangedAll()) { add('allChanged', true); } //  true,      -  if (isChangedAll('width', 'height', ...)) { const {width, height} = nextProps; add('size', width + 'x' + height); //     //   ,   setTimeout(() => this.changeSomething(), 0); //   - ,        //       componentDidUpdate call(() => { this.initNewSizes(width, height); }); } //   "add",   prop -  addIfChanged('name', value); addIfChanged('name'); //   "add",  - prop   PROPS_LIST -  addIfChangedAny('name', value); addIfChangedAny('name'); //      null //   ,  ,     //    console.log(get()); //     "add",      //      ,       "add" return { size: nextProps.width + 'x' + nextProps.height } } constructor(props) { super(props); //  "registerContext",    this   getDerivedStateFromProps //     ,     "registerContext",       registerContext(this); } //      componentDidUpdate(data) { const { prevProps, prevState, snapshot, changedProps, changed, isChanged, isChangedAny, isChangedAll } = data; if (isChanged('value')) { const {value} = this.props; this.doSomeAction(value); } } componentWillUnmount() { //    ,  "registerContext"     unregisterContext(this); } render() { const {style, size} = this.state; return ( <div className="container" style={style}> Size is {size} </div> ) } } export const Container = withStateMaster(ContainerComponent, PROP_LIST, INITIAL_STATE); 

If the component is inherited from another, pass the parent so that the parent getDerivedStateFromProps is called.


 export const Container = withStateMaster(ContainerComponent, PROP_LIST, null, ParentalComponent); 

This is my solution to this problem (although perhaps I didn’t understand the reactor enough, and this is not a problem at all).


Thus, I entered into resistance to the new canons of React, maybe some day I will accept and rewrite everything as it should.


Although the developers may again redo everything and there will be other pressing issues.
Everything, I lie down, and lying, as they say, do not beat.


')

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


All Articles