Declarative State

Even more important is that these components are declarative : they allow developers to specify what the UI should look like for a given state, and not have to worry about how to show that UI — Thinking in Relay

The pattern 's basic ideas:

  1. Components should only care about render a state without knowing how, when and from where.
  2. Components should declare a specification of the data needed to render.
  3. Data dependency definitions should live alongside component definitions, which makes it much easier to reason about what data a UI component requires to render. Looking at a file that contains a component definition, it’s immediately obvious what data it needs to function.

Component Composition

Complex, large state declarative components can be created by composing smaller components. There are 2 approaches:

  • Parent component could declare data shape for both children and itself.
  • Parent use _state.path(key) _to create sub-state for children which declare their own state requirements.
const TodoList = ({ state, title, todos }) {
  render() {
    return (
      <View>
        <Text>{title}</Text>
        {todos.map(key => <TodoItem state={state.path(["todos", key])} />)} //child with sub-state
      </View>
    );
  }
}

const TodoListWithState = gstate({
    title: 1,
    todos: {
       _: "$key" // todos.map((item, key) => key)
    }
}, (props, data) => (
    <TodoList state={props.state} title={data.title} todos={data.todos}/>
));

// declarce data on substate ["todos", key]
const TodoItem = gstate({
    text: 1,
    completed: 1
}, (props, data) => (
    <li style={{ textDecoration: data.completed ? "line-through" : "none"}}>
    {data.text}
    </li>
));

Notice the pattern is same with elm

view : Model -> Html Msg
view model =
    div
        [ class "todomvc-wrapper"
        , style [ ( "visibility", "hidden" ) ]
        ]
        [ section
            [ class "todoapp" ]
            [ lazy viewInput model.field                          // child component with sub state
            , lazy2 viewEntries model.visibility model.entries    // child component with sub state
            , lazy2 viewControls model.visibility model.entries   // child component with sub state
            ]
        , infoFooter
        ]

results matching ""

    No results matching ""