Single Entity Component
So the previous section was about a component that lists all the entities stored in an array, and it has the ability to add in new one through a click of a link. Now we would have to actually display a form to allow user to edit ONE publication.
render() {
return (
<fieldset>
<legend>Publication</legend>
<p>
<label>
title<br />
<input
onChange={this.handle_change}
name="title"
value={this.props.publication.title}
/>
</label>
</p>
<Persons
legend="Authors"
field="authors"
delegate_update={this.handle_update}
persons={this.props.publication.authors || [{}]}
/>
<p>
<label>
Type<br />
<select name="type" onChange={this.handle_change}>
<option disabled selected={this.props.publication.type || true}>
select
</option>
<option
value="journal"
selected={this.props.publication.type === "journal"}
>
Journal
</option>
<option
selected={this.props.publication.type === "book"}
value="book"
>
book
</option>
</select>
</label>
</p>
<p>{this.get_meta_widget()}</p>
<p>
<a onClick={this.handle_click} href="#">
Delete this publication
</a>
</p>
</fieldset>
);
}
We talk about this.get_meta_widget() later.
So in each publication, we can have a list of authors of arbitrary length as well, but we don’t do the listing here, and instead delegate the work to another component, and passing only handle_update of the first form mentioned in the first section.
Then we also have a delete button to remove this exact publication.
Here is the respective methods in the container.
export default connect(
state => ({}),
dispatch => ({
handle_change(e) {
e.preventDefault();
dispatch(
this.props.delegate_update(false, {
[e.target.getAttribute("name")]: e.target.value
})
);
},
handle_click(e) {
e.preventDefault();
dispatch(this.props.delegate_update(true));
},
handle_update(_, changes) {
return this.props.delegate_update(
false,
Object.assign({}, this.props.publication, changes)
);
}
})
)(PublicationWidget);
In order to delete itself, the component just needed to call delegate_update(true) without having to pass extra parameters to the function. It doesn’t need to know where it is in a list (because it was bound to the handle_update method.
OTOH when a change is happening, it needs to explicitly tell that it is not a deletion, as well as passing in the update to the original state. Good thing about the react-redux integration here is that I don’t have to worry about updating the input element because they would be reflected when a re-render takes place (I love this part so much I am going to mention it again).
Lastly the handle_update is done mainly for the component that lists authors. You will probably see it in action again later.