npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

react-hooks-usemodel

v1.0.5

Published

[![NPM](https://img.shields.io/npm/v/react-hooks-usemodel.svg)](https://www.npmjs.com/package/react-hooks-usemodel) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/e8cdc12c08644c36a8c672bdd45e049e)](https://www.codacy.com/manual/datnq/react-us

Downloads

18

Readme

react-hooks-usemodel

NPM Codacy Badge code style: prettier npm npm bundle size

Simplify usage of managing datasource and form's model

Install

Dependencies

Engine

{
  "node": ">=8",
  "npm": ">=5"
},

Package

{
  "lodash": "^4.17.15",
  "react": "^16.11.0",
  "react-dom": "^16.11.0",
  "sprintf-js": "^1.1.2"
}

Run install

# NPM
npm install --save react-hooks-usemodel

#Yarn
yarn add react-hooks-usemodel

Single datasource

App wrapper

// app.js or index.js
import { withData } from 'react-hooks-usemodel'
import App from './App'

const AppContainer = withData()(App)

ReactDOM.render(<AppContainer />, document.getElementById('root'))

With initial data

const AppContainer = withData({
  todos: [
    // initial data item
  ]
})(App)

In component

// todoList.js
const TodoList = ({data, dataSetter}) => {
  const { todos } = data
  // ...
}

export default subscribe({
  todos: []
})(TodoList)

Working with a model

Model's pubic interface

class Model {
  // Properties
  data { get; set; } // get/set value of all field in JSON object
  isValid { get; } // get valid state of model, true if all field is tested and valid
  fields { get; } // get all fields
  errors { get; } // get all field's error

  // included all fields as properties

  // Methods
  extractFromEvent(SyntheticEvent: e); // Utility method to set value from input's change event
  setData(data); // set fields' values from JSON object
  clearData(); // set all fields' values to undefined, also clear validation status
  validate(); // Validate all fields
}

Custom model

import { Model } from 'react-hooks-usemodel'

class CustomModel extends Model {
  // ...
}

Field's pubic interface

class Field {
  // Properties
  value { get; set; } // get/set field's value
  isValid { get; } // return valid status
  error { get; } // return field's validationError (undefined if not)
  validated { get; } // checked whether field's validated or not, init with false

  // Also inherit all the property which defined in model's instance
  
  // Methods
  validate(value); // Run through all validators and return true (if all valid) or validationError. If value is empty then validate current field's value
  clearValue(); // clear field's value and validation
  extractFromEvent(e); // Utility method to set value from input's change event
  setValue(value, conflictCheck = []); // set field's value
}

Custom field's type

// checkboxField.js
import { Field } from 'react-hooks-usemodel'

class CheckboxField extends Field {
  extractFromEvent(e) {
    const {
      target: { value, checked }
    } = e;
    this.setValue(checked ? value : null);
  }
}

// Usage, in model
// models/todos.js
export default () => {
  return {
    //...
    completed: {
      label: 'Completed',
      type: CheckboxField, // if we don't set type, model will use base Field class
      validators: [
        // list of validators
      ]
    }
    //...
  }
}

Define a model instance

// models/todos.js
import { required, minlen } from 'react-hooks-usemodel/dist/utils/validators'

export default () => {
  return {
    content: {
      label: 'Todo Content',
      validators: [
        { test: required(), errorMessage: '%(label)s is required' },
        { test: minlen(6), errorMessage: '%(label)s must be longer than 6 characters' },
      ]
    },
    completed: { // field with no validators will always be valid
      label: 'Completed',
      type: CheckboxField // field with custom Field's type
    }
  }
}

Use model in component

// import
import { useModel } from 'react-hooks-usemodel'

// in component
const todo = useModel(todoModel, defaultValue) // default value can be empty

// get Field from Model
const { content, completed } = todo

// Update data of a model, this will update multiple fields
todo.setData({ content: 'Todos content', completed: true })

// Update value of a field
completed.setValue(true)

// After update, state of component will be changed, component will be automatically re-render without manual setState

Validation

Builtin validators

// import
import {
  required,
  email,
  minlen,
  equal
} from 'react-hooks-usemodel/dist/utils/validators'

// usage
{ test: required() } // check if field is required
{ test: email() } // check if field's value is email
{ test: minlen(6) } // check if field's value is not longer than 6 characters
{ test: equal(10) } // check if field's value is equal to 10

Custom validators

// customValidators.js

// validator will always return valid case = true
const strongPassword = () => value => /^.*(?=.{8,})((?=.*[!@#$%^&*()\-_=+{};:,<.>]){1})(?=.*\d)((?=.*[a-z]){1})((?=.*[A-Z]){1}).*$/g.test(v)

// validator also use it's model as second argument
const retypePasswordMatch = () => (value, model) => {
  return value === model.password.value
}

// usage in model's field
{
  password: {
    // ...
    label: 'Password',
    validators: [
      {
        test: strongPassword(),
        // I'm using `sprintf-js` as error message generator, with parameters is field's properties
        // Error message is: sprintf(errorMessage, { ...field })
        // @see https://www.npmjs.com/package/sprintf-js for usage
        errorMessage: 'Your %(label)s is not strong enough'
      }
    ]
  },
  retypePassword: {
    label: 'Retype password',
    validators: [
      { test: retypePasswordMatch(), errorMessage: '%(label)s must match the Password' }
    ]
  }
}

Custom ValidationError

class ValidationError extends Error {
  // extra properties
  field, // instance of Field
  validator, // validator test function
}

Clone from source

git clone https://github.com/datnq/react-use-model

License

MIT © 2019 by Joey Nguyen