0.9.0 • Published 5 years ago

react-vm v0.9.0

Weekly downloads
3
License
ISC
Repository
github
Last release
5 years ago

A tiny library that enables old school MVC, MVVM, MVWhatever approach with React.

Usage

Given that you have a component that needs to be smart called <Todo />. You can write it's business logic in plain ES6 class like this:

export class TodoController {

  items = [];

  // method receives props passed to <Todo />
  $mount({ prop }) {
    console.log('Todo: Initialized with ', prop);
  }

  $unmount() {
    console.log('Todo: Destroyed!');
  }

  toggleDone(index) {
    this.items[index].done = !this.items[index].done;
  }

  addItem(description) {
    this.items.push({
      description,
      done: false,
    })
  }

}

Than you can use this controller as initialized object in your component:

import { useViewModel } from '../viewmodel';

export function Todo() {
  const vm = useViewModel();

  // in case you don't want to pollute your business logic with a controlled input
  const [description, setDescription] = useState('');

  return (
    <ul>
      <li>
        {vm.count}
        <button onClick={() => vm.increment()}>Increment</button>
      </li>
      <li>
        <input type="text" value={description} onChange={e => setDescription(e.target.value)} />
        <button onClick={() => vm.addItem(description)}>Add</button>
      </li>
      {vm.items.map((item, index) =>
      <li key={index}>
        <label>
          <input type="checkbox" checked={item.done} onChange={() => vm.toggleDone(index)} /> {item.description}
        </label>
      </li>
      )}
    </ul>
  );
}

You only have to pair the component and the controller to create a so called viewModel (this might be not how it's called at all, i am still confused):

import { Todo } from './Todo';
import { TodoController } from './TodoController';
import { viewModel } from '../viewmodel';

export default viewModel(Todo, TodoController);

All the changes on the controller instance are triggering rerendering on the react component.

Wondering how it works? Take a look at the code. It's simple and very ugly.

DISCLAIMER: This is just a prototype of an idea and is implemented in a very non-efficient way. It most probably does not cover a lot of use cases as it was not tested on large scale apps. If you think this is a terrible idea, I'd happily like to know why.

0.9.0

5 years ago

0.8.0

5 years ago

0.7.0

5 years ago

0.6.0

5 years ago

0.5.1

5 years ago

0.5.0

5 years ago

0.4.0

5 years ago

0.3.0

5 years ago

0.2.1

5 years ago

0.2.0

5 years ago

0.1.0

5 years ago

0.0.1

5 years ago