W
W
Worddoc2018-02-13 19:04:29
JavaScript
Worddoc, 2018-02-13 19:04:29

Why doesn't inner React component render after state change?

Hello! The problem is that the Form component, some elements of which depend on the state, is not rendered. In the react devtools, you can see that the state is changing normally. I recently started learning React and I have no idea what could be the problem. Please help. Thank you.

class Row extends React.Component {
    constructor(props) {
        super(props)
        this.removeClickHandler = this.props.removeClickHandler;
        this.changeClickHandler = this.props.changeClickHandler;
    }

    render() {

        return (
            <tr className="app__row">
                <td className="app__cell app__cell--name">{this.props.name}</td>
                <td className="app__cell app__cell--phone">{this.props.phone}</td>
                <td className="app__cell app__cell--action">
                    <button 
                        className="app__cellButton btn"
                        onClick={this.removeClickHandler}>REMOVE
                    </button>
                    <button 
                        className="app__cellButton btn"
                        onClick={this.changeClickHandler}>CHANGE
                    </button>
                </td>
            </tr>
        );
    }
}

class Table extends React.Component {
    constructor(props) {
        super(props)

    }

    makeRows() {
        return this.props.people.map((item,index) => {
            return <Row 
                    name={item.name} 
                    key={index}
                    phone={item.phone} 
                    removeClickHandler={this.props.removeClickHandler}
                    changeClickHandler={this.props.changeClickHandler}/>
        })
    }

    render() {
        return (

            <table>
                <thead>
                    <tr>
                        <th>Name</th>
                        <th>Phone</th>
                        <th>Action</th>
                    </tr>
                </thead>
                <tbody>
                    {this.makeRows()}
                </tbody>
            </table>
        )
    }
}

class Form extends React.Component {
    constructor(props) {
        super(props)
        this.onClickHandler = this.props.onClickHandler;
        this.onPutInputHandler = this.props.onPutInputHandler;
        this.isFormStateChange = this.props.isFormStateChange;
    }


    render() {
        return (
            <React.Fragment>
                <input 
                    className="app__nameInput"
                    type="text"
                    data-type="name"
                    value={this.props.nameValue}
                    onChange={this.onPutInputHandler}
                    placeholder={this.isFormStateChange === false ? "Type a name..." : ""}/>
                <input 
                    className="app__phoneInput"
                    type="text"
                    data-type="phone"
                    value={this.props.phoneValue}
                    onChange={this.onPutInputHandler}
                    placeholder={this.isFormStateChange === false ? "Type a phone..." : ""}/>
                <input 
                    className="app__submitButton btn"
                    value={this.isFormStateChange === false ? "ADD" : "SAVE CHANGES"}
                    type="submit"
                    onClick={this.onClickHandler}/>
            </React.Fragment>
        )
    }
}


class App extends React.Component {
  constructor(props) {
    super(props);
    
    let people = [
      {
        name: 'John',
        phone: '+7(915)5554522'
      },
      {
        name: 'Chinda',
        phone: '+7(915)5552565'
      },
      {
        name: 'Mike',
        phone: '+7(915)6546546'
      },
      {
        name: 'Lara',
        phone: '+7(915)8793453'
      },
      {
        name: 'Borines',
        phone: '+7(915)6456325'
      },
      {
        name: 'Maria',
        phone: '+7(915)8673453'
      }
    ]

    this.state = {
      data: people,
      inputName: '',
      inputPhone: '',
      isFormStateChange: false
    }

    this.onPutInputHandler = this.onPutInputHandler.bind(this);
    this.onClickHandler = this.onClickHandler.bind(this);
    this.removeClickHandler = this.removeClickHandler.bind(this);
    this.changeClickHandler = this.changeClickHandler.bind(this);
  }

  onClickHandler(e) {
    e.preventDefault();
    if (this.state.inputName.length <= 0 || this.state.inputPhone.length <= 0) return;
    this.setState(prev => ({
      data: prev.data.concat([{
        name: this.state.inputName,
        phone: this.state.inputPhone
      }]),
      inputName: '',
      inputPhone: ''
    }))
  }

  onPutInputHandler(e) {
    let input = e.target;

    e.preventDefault();
    if (input.dataset.type === 'name') {
      this.setState({inputName: input.value})
    } else if (input.dataset.type === 'phone') {
      this.setState({inputPhone: input.value});
    }

  }

  removeClickHandler(e) {
    let personData = {
      name: e.currentTarget.parentElement.parentElement.querySelector('.app__cell--name').innerHTML,
      phone: e.currentTarget.parentElement.parentElement.querySelector('.app__cell--phone').innerHTML
    };
    this.setState((prev) => ({
      data: prev.data.filter((item) => {
        if (item.name === personData.name && item.phone === personData.phone) return false;
        return item;
      })
    }));
  }

  changeClickHandler(e) {
    let person = {
      name: e.currentTarget.parentElement.parentElement.querySelector('.app__cell--name').innerHTML,
      phone: e.currentTarget.parentElement.parentElement.querySelector('.app__cell--phone').innerHTML
    }
    this.setState({isFormStateChange: true})
  }

  render() {
    return (
      <div>
        <Form 
          onClickHandler={this.onClickHandler}
          onPutInputHandler={this.onPutInputHandler}
          nameValue={this.state.inputName}
          phoneValue={this.state.inputPhone}
          isFormStateChange={this.state.isFormStateChange}/>

        <Table 
        people={this.state.data}
        removeClickHandler={this.removeClickHandler}
        changeClickHandler={this.changeClickHandler}/>
      </div>
    )
  }
}


ReactDOM.render(<App />, document.querySelector('.app'));

Answer the question

In order to leave comments, you need to log in

1 answer(s)
0
0xD34F, 2018-02-13
@Worddoc

The problem is that the Form component, some elements of which depend on the state, is not rendered.

"Some" is, apparently, inputs (placeholders) and a button (text). Why are they not updated - yes, because the isFormStateChange value of the form on which they depend (by the way, not "on the state" - you don't have a state there, what kind of nonsense?), Is set only once, in the constructor, and changing the isFormStateChange of the parent The component does not affect it in any way.
I take it you were looking for something like this ?

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question