React Address Edit

Elvenware Logo

TOC

React Address Edit

We have several steps that will allow us to start editing the data we view:

Create Tests

Please read this one section from Elvenware:

Create AddressEdit

Make a copy of AddressShow. Rename the class from AddressShow to AddressEdit. Must be done in at least two places. Strip out everything except the render method.

Here is an example:

<input id="elfFN" className="App-intro" value={this.props.address.firstName} onChange={this.props.onNameChange}/>

Hint

shallow can see all the HTML tags in a render method, but it can't see into the sub-components. Consider this code:

render() {
    if (!this.quiet) { console.log("ADDRESS RENDER"); }
    return (
        <div className="App">
            <MyAddress />
        </div>
    );
}

shallow can see that this render method contains a second React component called MyAddress, but it can't see the render method of MyAddress. mount can see into MyAddress. This means it can find the list items or paragraphs that may be listed as part of the MyAddress react Component. In cases like that shown above, it can see the render method of MyAddress, but shallow cannot.

Just to be clear, it would not matter how many divs, list items, paragraphs or other tags were included in the render method shown above. shallow could see them all. But it could not see into the contents of the render method of MyAddress.

Teach Address to Load AddressEdit

All you need to do is add a new method for handling changes to the input control:

onNameChange = (event) => {
    this.log("ON NAME CHANGE");
    const address = addresses[this.addressIndex];
    switch (event.target.id) {
        case 'elfFN':
            address.firstName = event.target.value;
            break;
        case 'elfLN':
            address.lastName = event.target.value;
            break;
        // ETC
        default:
            throw new Error('OH NO BAD CASE in Address onNameChange');
    }
    this.setState({
        address: address
    })
};

As you can see, key information about the user's action are passed in the target object that lives like a craven parasite on the event object. Note that:

To display the AddressEdit component, modify the Address render method to teach it to load AddressEdit:

<AddressEdit
    address={this.state.address}
    onAddressChange={this.onAddressChange}
    onNameChange={this.onNameChange}
/>
<AddressShow
    address={this.state.address}
    onAddressChange={this.onAddressChange}
 />

When you are done, edits to the INPUT should automatically propogate to the paragraph controls.

ElfTestDebug

Save as ElfEnzymeDebug.js in the root of your project.

The Source is here:

And use it like this:

import ElfTestDebug from '../ElfTestDebug';
const elfTestDebug = new ElfTestDebug(true);

elfTestDebug.getFirst(...);

Contains Matching

Don't call wrapper.contains. Instead call wrapper.containsMatchingElement. You can still block copy the thing you want to match from your debug output, but don't include the onChange event.

fit('renders and displays the default value for firstName', () => {
    const wrapper = mount(<AddressChanger />);
    elfTestDebug.getFirst(wrapper, 'input');
    const welcome = <input id="elfFirstName" className="App-intro" value="unknown" />;
    expect(wrapper.containsMatchingElement(welcome)).toEqual(true);
});

Turn it in

Add, commit, push. Tag. Push your tag.

Hint Tagging