0

I'm building a React app and trying to see if I can do the following. there are a lot of nested component and the one being updated is always the top parent.

The idea is to build it through nested object prototyped via ES6 class like this:

class _Board {
    constructor(setStateFunction){
        this.items = [];
        this.setState = setStateFunction;
    }

    addSwimlane() {
        console.log(this);
        this.items = [...this.items, new _Swimlane()];
        this.setState(this);
    }
}

class _Swimlane {
    constructor(){
        this.id = uuidv4();
        this.items = [];
    }

    addColumn() {
        this.items = [...this.items, new _Column(this.id)];
        //Can we call the parent function through super to update the render?
    }
}

I then have my component in which I would call the function:

const Main = (props) => {
    const [board, setBoard] = useState(new _Board());
    
    useEffect(() => { //Initial Render load setState
        setBoard(new _Board(setBoard));
    }, []);

    return (
        <div className="App" >
            {JSON.stringify(board)}
            <button onClick={() => board.addSwimlane()} >Add Swimlane</button>
        </div>
    );
};

I have two question:

  1. How do you pass function like this in a class? I am able to pass them through arrow function like normal but when passed as parameter, the render doesn't update.
  2. How do you call the parent class once the children has been nested? Should I pass the function through the "addX" function I already have and it will be there as reference?
Johnny Prescott
  • 263
  • 6
  • 23
  • I am not quite what you mean by, "how do you call the parent class once the children has been nested", could you reword it? – kyle Mar 08 '21 at 03:42
  • 1
    This is absolutely not the correct way to write React. Whether or not it works is irrelevant, do things the React way or you'll be running into major problems and no one will be able to help you cos your code is all crazy and super hard to understand. If you want to store a row/column like data structure, just do it directly in React's state. You also shouldn't be setting state from external places, like a class instance. Always be setting state directly inside the component itself. Sometimes you have to do weird stuff, but not in simple use cases like this – Jayce444 Mar 08 '21 at 03:54
  • For your use case, you literally just need to store an array of `uuidv4()`s in state, and build your components from that. That's all – Jayce444 Mar 08 '21 at 03:55
  • You are attempting to share state. There are a number of ways to accomplish that. Check out this answer for one method you may find interesting: https://stackoverflow.com/a/38904385/9078341 – Randy Casburn Mar 08 '21 at 03:58
  • Why would building my state from a templated class be wrong exactly? It's no different from just setting the state as an object. The only time the class is used is on the intial useState, then it just become an object. I want to know how to give that object the ability to call setState for itself. – Johnny Prescott Mar 08 '21 at 04:37
  • what is the parent function you want to call ? And who should call it ? a child (Swimlane ?) ? – grodzi Mar 08 '21 at 06:26
  • @grodzi when I call "addSwimlane", it calls "this.setState" which is passed from parameters. Should that be working and re-rerender since that's the original SetState from the component? – Johnny Prescott Mar 08 '21 at 16:45
  • your question can thus be narrowed down to: when does setState triggers a merge and rerender on a instance. It seems if you keep the same reference it does not rerender. You may consider storing a simple 'json' instead. And rebuild an object based on that json every time + giving to setState a stringified version representing the...**state** of that object – grodzi Mar 08 '21 at 19:40

0 Answers0