Существует несколько способов синхронизировать состояние компонентов с другим источником данных (т. Е. Объектом gun
) - один простой подход заключается в кэшировании копии данных todo
, которые вы планируете визуализировать, в компоненте.state
.
Это делается с помощью функции setState()
, которая при вызове вызывает повторную визуализацию компонента.В случае использования метода render()
вашего компонента изменение поля состояния todos
обновит список для отображения.
При таком подходе вам нужно будет убедиться, что при внесении изменений в gun
Данные объекта todos, вы также обновляете состояние компонентов todo
через setState()
, как показано ниже:
constructor(props) {
super(props)
/* Setup inital state shape for component */
this.state = {
todos : [],
newTodo : ''
}
}
mapTodos() {
return this.gun.get('todos').map((value, key) => ({ key : key, val : value }));
}
componentDidMount() {
this.gun.on('auth', () => this.mapTodos());
}
handleChange = e => this.setState({ newTodo: e.target.value })
add = e => {
e.preventDefault()
this.gun.get('todos').set(this.state.newTodo)
/* When adding a todo, update the todos list of the component's internal state
to cause a re-render. This also acts as a cache in this case to potentially speed
up render() by avoiding calls to the gun.get() method */
this.setState({ newTodo: '', todos : this.mapTodos() })
}
del = key => {
this.gun.get(key).put(null)
/* Call setState again to update the todos field of the component state to
keep it in sync with the contents of the gun object */
this.setState({ newTodo: '', todos : this.mapTodos() })
}
render() {
return <Container>
<div>Gun</div>
<div>
<form onSubmit={this.add}>
<input value={this.state.newTodo} onChange={this.handleChange} />
<button>Add</button>
</form>
<br />
<ul>
{this.state.todos.map(todo => <li key={todo.key} onClick={ () => this.del(todo.key) }>{todo.val}</li>)}
</ul>
</div>
</Container>
}