React Introduce

What's React ?

A Javascript library for building user interfaces .

What's React ?

  • Just the UI
  • Virtual DOM
  • Data flow

Just The UI

  • Just view (mVc)
  • Declarative (JSX)
  • Component (props => <Component />)

Virtual DOM

  • Abstract (Node, React Native)
  • Immutable (shim mutable(imperative) DOM API)
  • Performance (dom diff)

Data Flow

  • One-way reactive data flow
  • Flux, Redux

Flux Architecture

Flux

Redux

Flux vs Redux

  • stores VS singleton store
  • callback registration VS functional composition

Problem

  • State management is complicated (database)
  • Empty props before data fetched (server data)
  • Imperative props load (declarative)

Traditional MVC

Flux

MVC In Frontend

MVC In Frontend

  • Model (falcor)
  • Controller (react-router, action: middleware)
  • View (component)

What's Falcor

  • One model everywhere
  • The data is the API
  • Bind to the cloud

JSON Graph

    {
        todosById: {
            "44": {
                name: "get milk from corner store",
                done: false,
                prerequisites: [{ $type: "ref", value: ["todosById", 54] }]
            },
            "54": {
                name: "withdraw money from ATM",
                done: false,
                prerequisites: []
            }
        },
        todos: [
            { $type: "ref", value: ["todosById", 44] },
            { $type: "ref", value: ["todosById", 54] }
        ]
    }
    
    get(["todos", 0, "prerequisites", 0, "name"])

Data-model And UI-model

  • Data-model: server maintain
  • Data-model.filter(UI-model) + UI-model (props)

Data-model And UI-model



    export const dataModel = new falcor.Model({
        source: new HttpDataSource(url),
    })
    
    export const uiModel = new falcor.Model({
        cache: {
            articleList: { page: 1 },
        },
    })

Data model (Restful API)



const greeting = [{
    route: 'greeting.rules[{keys:ids}]',
    get: async pathset => {
	const query = { sceneId: pathset.ids[0] }
	const rules = await weini.get('/manager/warm_up/index').
            query(reverseCamelcase(query)).
	    json().
	    then(body => toCamelcase(body.result))
        return {
	    path: pathset,
	    value: $atom(rules),
	}
    },
}]

Self-synchronizing

  • Ideal: falcor $ref
  • Degradation: model.invalidate(…path)
  • Degradation: model.setCache(null)

Controller

  • Routes: route => component (template)
  • Async-props: route => props (data)
  • Action: route => operator (middleware)

Async-props

  • Base on react-router
  • Define loadProps in each route component
  • Fetch all props data before render

Action


// action/signin.js

    export const loadProps = async (params, location) => {
	const response = await uiModel.get(['signin', ['username', 'password']])
	const { username, password } = response.json.signin
	const query = queryString.parse(location.search)
	const { redirect = '/' } = query
	return { username, password, redirect: decodeURIComponent(redirect) }
    }

    export const handleChange = async (key, value) => {
    	await uiModel.setValue(['signin', key], value)
    	return global.reload('signin: handleChange', key, value)
    }


// container/app/signin.jsx
    
    const SigninContainer = props => <Signin {...props} />
    SigninContainer.loadProps = loadProps
    export default SigninContainer

Async-props + Falcor

Pros

  • State is clearly (model)
  • Avoid empty props

  • Declarative props load
  • Server-render is easy
  • Stateless component

Cons

  • First load is slow
  • Falcor VS Restful API

Component

  • Stateless component 
  • Grained control

  • Component style

Component

  • Decouple: html/css/js -> components

  • CSS reuse: CSS localization & Component reuse

Stateless Component

  • props => <Component />
  • Testable
  • Robust

Grained Control

  • Semantic structure

  • Route structure

  • Repeated use

Component Style

  • CSS in JS (bug, lose power)

  • ClassName hooks (class dirty, lose semantics)

  • CSS modules (class dirty, destructive)

Component Style

  • Global component (<admin-signin>...</<admin-signin>)

  • Local component (<div data-username>)

Composed Component


    const Username = ({ username }) => (
      <div data-username>
        <label>
          <strong>用户名</strong>
          <TextField name="username" defaultValue={username} required
              autoFocus onChange={e => handleChange('username', e.target.value)} />
        </label>
      </div>
    )

    const Signin = props => {
      const { username, password, redirect } = props
      return (
        <admin-signin>
          <form onSubmit={...}>
            <Username username={username} />
            <Password password={password} />
            <Submit />
          </form>
        </admin-signin>
      )
    }
    export default Signin

Conclusion

  • React just a declarative view library
  • MVC in frontend
  • Component

React Introduce

By jiawei chen

React Introduce

React Introduce

  • 937