The Author Online Book Forums are Moving

The Author Online Book Forums will soon redirect to Manning's liveBook and liveVideo. All book forum content will migrate to liveBook's discussion forum and all video forum content will migrate to liveVideo. Log in to liveBook or liveVideo with your Manning credentials to join the discussion!

Thank you for your engagement in the AoF over the years! We look forward to offering you a more enhanced forum experience.

tempusfugit (144) [Avatar] Offline
#1
(Listing 5.4 actually ...)
Needs this.state initialized in the constructor as shown in "Updating component state using Inputs" later otherwise this.state.content will crash in render.
import PropTypes from 'prop-types';
import React, {Component} from 'react';

const initialState = () => ({
  content: ''
});

class CreatePost extends Component {
  constructor(props) {
    super(props);
    this.state = initialState();
  }

  handlePostChange = (e) => {
    console.log("Handling an update to the post body!");
    console.log(e);
  };

  handleSubmit = (e) => {
    console.log('Handling submission!');
  };

  render() {
    const onClick = this.handleSubmit;
    const { content: value } = this.state;
    const onChange = this.handlePostChange;

    return <div className="create-post">
        <button {...{ onClick }} >Post</button>
        <textarea {...{ value, onChange, placeholder: 'What\'s on your mind?' }} />
      </div>;
  }
}

CreatePost.propTypes = {
};

export default CreatePost;

Using uncontrolled components
Something like

import PropTypes from 'prop-types';
import React, {Component} from 'react';

// https://reactjs.org/docs/uncontrolled-components.html
// https://goshakkk.name/controlled-vs-uncontrolled-inputs-react/
// https://reactjs.org/docs/forms.html#controlled-components

class CreatePost extends Component {
  constructor(props) {
    super(props);
  }

  handleSubmit = _event => {
    const { value: content } = this.input; // (3) Using copied reference to reach
    console.log(content);                  // into DOM element and retrieve value
  };

  copyInputRef = input => {
    this.input = input; // (1) function to capture DOM element reference
  };                    // to "this.input" component instance field

  render() {
    const onClick = this.handleSubmit;
    const ref = this.copyInputRef; // (2) ref prop to capture textarea DOM element reference

    return <div className="create-post">
        <button {...{ onClick }} >Post</button>
        <textarea {...{ ref, placeholder: 'What\'s on your mind?' }} />
      </div>;
  }
}

CreatePost.propTypes = {
};

export default CreatePost;

may have been clearer in communicating the intent of an uncontrolled component - i.e. to leave the "input state" within the DOM element to be retrieved at a later point in time (e.g. when the Post button is clicked).

The end of chapter 5 still seems rushed/unfinished as the last step to completing Create.js is skipped (though it can be gleaned from the chapter-5 branch code). For anybody interested, I ended up with
import PropTypes from 'prop-types';
import React, {Component} from 'react';

import Filter from 'bad-words';

const filter = new Filter();

const initialState = () => ({
  content: '',
  valid: false
});

const isContentValid = (content) =>
  content.length <= 280;

class CreatePost extends Component {
  constructor(props) {
    super(props);
    this.state = initialState();
  }

  handlePostChange = event => {
    const { target: { value: rawContent } }  = event;
    const content = filter.clean(rawContent);
    const valid = isContentValid(content);
    this.setState(() => ({ content, valid }));
  };

  handleSubmit = e => {
    const { content, valid } = this.state;
    if(!valid) {
      return;
    }
                                     // the following was arrived at by looking
    const { onSubmit } = this.props; // at the chapter-5 branch
    onSubmit({ content });           // src/components/post/Create.js code
    this.setState(initialState);     // and can't befound in the text
  };

  render() {
    const onClick = this.handleSubmit;
    const { content: value } = this.state;
    const onChange = this.handlePostChange;

    return <div className="create-post">
    <button {...{ onClick }} >Post</button>
    <textarea {...{ value, onChange, placeholder: 'What\'s on your mind?' }} />
    </div>;
  }
}

CreatePost.propTypes = {
  onSubmit: PropTypes.func.isRequired
};

export default CreatePost;

// FYI: use the chapter-5 branch app.js as-is;
// the rest of the application is wired with Redux
// ignore "Handling post submissions (src/app.js)"
// ignore "Passing callbacks as props (src/app.js)"

Also it seems that the chapter-5 branch is more like a "chapter-6" branch as it also includes use of mapbox which should presumably be only complete by the end of chapter 6 (apart from the fact that Redux is already well integrated, which is only a Chapter 10 topic).
mark (60) [Avatar] Offline
#2
Hey there!
Thanks for your posts! I think some of these issues (like the configuration one w/ firebase and others) may have already been resolved in the production version of the book (that's where it's at in the process right now), but I'll take a look to make sure things weren't left out. Thanks and hope you enjoy the book!

Best,

Mark