Accessing State in Components
Converting a React Component to Engine view allow accessing
todos from state In src/App.tsx
:
- const App = () => (
+ const App: view = ({ todoIds = observe.visibleTodoIds }) => (
<section className="todoapp">
+ {console.log("TODOS", todoIds)}
App
component is labeled as aview
- In
App
's header,observe.visibileTodoIds
allow readingState.visibileTodoIds
Todos ids from state can be seen printed in console! Engine allow observing any
part of the state by assigning it as observe.<path>
in header of a view
.
All engine operator types are available globally. Check them out in global.ts
.
Extract the <Todo>
component out of<App>
to easily map
todo ids toTodo
components, and put it in its own file. In src/Todo.tsx
, add
const Todo = ({ id }) => (
<li>
<div className="view">
<input className="toggle" type="checkbox" />
<label>{id}</label>
<button className="destroy" />
</div>
</li>
);
export default Todo;
Update the App
component with:
+ import Todo from './Todo';
...
<ul className="todo-list">
- <li>
- <div className="view">
- <input className="toggle" type="checkbox" />
- <label>Give life to my TODOs</label>
- <button className="destroy" />
- </div>
- </li>
+ {todoIds.map((id: string) => (
+ <Todo id={id} key={id} />
+ ))}
</ul>
As per the implementation ofTodo
, it is possible to see todo ids(i.etodo1
,
todo2
) in browser. But it should actually showTodoItem.title
, not their
id.
This is where Engine differs from traditional React apps. Engine recommends that
[parent component should pass minimal data to its children](docs / best -
practices#pass - minimal - data - to - children). Minimum amount of data needed
to render a Todo
is its id
. Right todo can be retrieved from global state
with its id. Modify the Todo
component to follow the Engine way:
Insrc/Todo.tsx
- const Todo = ({ id }) => (
+ const Todo: view = ({ title = observe.todosById[prop.id].title }) => (
<li>
<div className="view">
<input className="toggle" type="checkbox" />
- <label>{id}</label>
+ <label>{title}</label>
<button className="destroy" />
</div>
</li>
);
Todo
is converted to a view (by labeling it withview
macro)- Assigning
title
toobserve.todosById[prop.id].title
in view header gives access to the title of a todo from the global state
prop allow composing
paths for accessing data from global
state. prop.<path>
gives access to all the React
props passed to a component
by its parent.
Every view
in Engine can access any data path from Engine's global state.
Trick is getting the right thing. The input macros help achieving clever ways of
path composition to get the
right data into views.
observe.todosById[prop.id].title
tells Engine to look-up a todo with prop.id
in todosById
object of the global state, and observe its title
property. This
gives read-only access to title
.
This also ensures that the view gets re-rendered whenever title
property of
todo with id prop.id
changes. Any other changes that happen in the state, even
in the todo itself will not affect the view.