Reputation: 65
I'm struggling to make use of an object in react, I'm trying to access the key:value that is being returned (and I can successfully console.log).
All the examples I've tried result in either mapping each character or throwing an object child error and i'm at a loss.
componentDidMount() {
this.gun.on('auth', () => this.thing());
}
thing() {
this.gun.get('todos').map((value, key) => { console.log(key, value) }
);
}
handleChange = e => this.setState({ newTodo: e.target.value })
add = e => {
e.preventDefault()
this.gun.get('todos').set(this.state.newTodo)
this.setState({ newTodo: '' })
}
del = key => this.gun.get(key).put(null)
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></>
}
}
Upvotes: 3
Views: 158
Reputation: 30370
There are a few ways to synchronize your components state with another data source (ie the gun
object) - one simple approach would be to cache a copy of the todo
data that you plan to render, in your component's state
.
This is done via the setState()
function which when called, causes the component to re-render. In the case of your component's render()
method, changing the todos
state field will updated list to display.
With this approach, you'd need to ensure that when you make changes to the gun
object's todos data, you also update the components todo
state via setState()
as shown below:
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>
}
Upvotes: 1