-
Notifications
You must be signed in to change notification settings - Fork 9
Component
Component
is a wrapper component for taking data from the global state and providing it as props to the child component(s). The Tide Component keeps tracks of changes in the listened to state, and re-renders the child whenever necessary. This way the child component can be kept as a pure react component, only rendering from the props it receives.
import {Component as TideComponent} from 'tide'
class App extends React.Component {
render() {
return (
<div className='app'>
<TideComponent todos={['todos']}>
{props => <TodoList {...props} />}
</TideComponent>
</div>
)
}
}
The todos
property given to the Tide Component above is an array specifying a path in the global state, which will be used with the Immutable getIn
method to retrieve the data. The child TodoList
component will receive the data in this.props.todos
.
Instead defining key paths with ['nested', 'path']
, you can also use dot notation: 'nested.path'
. Alternatively, you can pass a function that creates the key path:
<TideComponent todoItem={(state, options) => ['todos', state.get('activeTodoItem')]}>
{props => <TodoItem {...props} />}
</TideComponent>
The function is called with two arguments:
-
state
: The global Tide state. -
options
: An options object defined by setting atideOptions
prop onTideComponent
. This will be available to all children in the subtree of the component.
As an alternative to using Component
to send down props to a rendered child component, you can also define the child component class to automatically be wrapped within a Component
with the given key paths. This is done using the Tide.wrap
method:
import {wrap} from 'tide'
const ChildComponent = React.createClass(...)
export default wrap(ChildComponent, {data: 'path.to.data'})
This can then be rendered simply as:
render() {
return (
<div className='parent-component'>
<ChildComponent otherProp={true}/>
</div>
)
}
Which is equivalent to the following (not using Tide.wrap
):
import {Component as TideComponent} from 'tide'
render() {
return (
<div className='parent-component'>
<TideComponent data='path.to.data'>
{props => <ChildComponent {...props} otherProp={true}/>}
</TideComponent>
</div>
)
}
The Tide Component wrapper will send down one extra property to the child - this.props.tide
- which includes a number of nested properties.
All of the registered actions on the tide instance. Your TodoActions
added with tide.addActions('todo', TodoActions)
will be available in this.props.tide.actions.todo
.
All of the used key paths to define the properties used from the global state. These are useful when nesting even further into the state object in the children of this component, such as when rendering items from a list:
class TodoList extends React.Component {
renderTodos() {
const {todos, tide} = this.props
// Todos given from <Tide todos={['todos']}/>
return todos.map((item, index) => (
<Tide
key={item.get('id')}
todo={tide.keyPaths.todos.contact([index])}
>
{props => <TodoItem {...props} />}
</Tide>
))
}
}
This gives each todo item in the list its own cursor, and when that particular todo in the list updates the item will re-render, without triggering re-renders in all of the other untouched items in the list.
A boolean indicating whether the component is impure or not. A pure component (where impure
is not set) will only re-render whenever any of the global state that it listens to changes, regardless of any external changes to the children or re-renders further up the tree. To change the component to always re-render, set impure
to true:
<Tide impure foo={['bar']}>
{props => <Child {...props} />}
</Tide>
However, before doing this you should first consider if all of the data that the component renders from could live in the global state instead.