V
V
Viktor Volkov2018-12-10 21:38:55
React
Viktor Volkov, 2018-12-10 21:38:55

Why is the component not being refactored?

Task sheet TODO. In general, if I want to create a new list item, then it is updated only after any other operations (deletion, status estimate):

class App extends React.Component {
        constructor() {
            super();
            this.state= {
                tasks: [
                    {name: 'Присесть 10 раз', status: false},
                    {name: 'Присесть 1280 раз', status: false},
                    {name: 'Присесть 180 раз', status: false},
                    {name: 'Прочитать 20 стр.', status: false}
                ]
            }
        }

        deleteItem(num) {
            this.state.tasks.splice(num.i, 1); //удаляю указанный пункт
            this.setState({tasks: this.state.tasks}); //изменяю стэйт
            //console.log("Del" + this.state.tasks);;
            console.log(num.i);
        }

        changeStatus(num) {
            this.state.tasks[num.i].status=!this.state.tasks[num.i].status; //меняю статус на противоположный
            this.setState({tasks: this.state.tasks}); //изменяю стейт
            console.log(this.state.tasks);

        }

        createItem(task) {
            console.log(task);
            this.state.tasks.unshift({name: task, status: false});
            this.setState({tasks: this.state.tasks});
            console.log(this.state.tasks);


        }

        render() {
            return <div>
                <CreateItem
                    createItem={this.createItem.bind(this)}
                />
                <br />
                <TableItem
                    tasks={this.state.tasks}
                    deleteItem={this.deleteItem.bind(this)}
                    changeStatus={this.changeStatus.bind(this)}
                />
            </div>;
        }
    }


    class CreateItem extends  React.Component {
        constructor(props) {
            super(props);
            this.state= {item:''}
        }

        handleChange(event) { //делаю двустороннюю зависимость, чтобы менялось содержимое input
            this.setState({item: event.target.value});
        }

        handleButton() {
            this.props.createItem(this.state.item);
            this.setState({item: ''});
            
        }

        render() {
            return <div>
                <input onChange={this.handleChange.bind(this)} value={this.state.item}/>
                <button onClick={this.handleButton.bind(this)}>create</button>
            </div>

        }
    }

    class TableItem extends  React.Component {
        constructor(props) {
            super(props);
            this.point = '';
            this.list = {};

            this.state = {
                list: this.props.tasks.map((e, i) => {
                    const status = e.status ? 'green' : 'red';

                    return <tr key={i}>
                        <td onClick={this.myChangeStatus.bind(this, {i})} style={{color: status}}>{e.name}</td>
                        <td>
                            <button onClick={this.myDeleteItem.bind(this, {i})}>delete</button>
                            <button onClick={this.makeList.bind(this, {i})}>edit</button>
                        </td>
                    </tr>;
                })
            }
            ;


        }

        myChangeStatus(num) {

            this.props.changeStatus.bind(null, num)();

            this.setState({
                list: this.props.tasks.map((e, i) => {

                    const status = e.status ? 'green' : 'red';

                    return <tr key={i}>
                        <td onClick={this.myChangeStatus.bind(this,{i})} style={{color: status}}>{e.name}</td>
                        <td>
                            <button onClick={this.myDeleteItem.bind(this, {i})}>delete</button>
                            <button onClick={this.makeList.bind(this, {i})}>edit</button>
                        </td>
                    </tr>;
                })
            });
        }


        myDeleteItem(num) {

            this.props.deleteItem(num);

            this.setState({
                list: this.props.tasks.map((e, i) => {
                    const status = e.status ? 'green' : 'red';

                    return <tr key={i}>
                        <td onClick={this.myChangeStatus.bind(this,{i})} style={{color: status}}>{e.name}</td>
                        <td>
                            <button onClick={this.myDeleteItem.bind(this, {i})}>delete</button>
                            <button onClick={this.makeList.bind(this, {i})}>edit</button>
                        </td>
                    </tr>;
                })
            });


        }


        makeList(num = "undefined") {

            this.point = num.i;
            console.log(this.point);

            //формирую список задач
            //привязываю к клику метод родителя App, и передаю наверх (через .bind(null, param )) номер элемента массива, который нужно удалить
            this.setState({
                list: this.props.tasks.map((e, i) => {
                    const status = e.status ? 'green' : 'red';

                    return <tr key={i}>
                        {i == this.point ? <input /> : <td onClick={this.props.changeStatus.bind(null, {i})} style={{color: status}}>{e.name}</td>}
                        <td>
                            <button onClick={this.props.deleteItem.bind(null, {i})}>delete</button>
                            <button onClick={this.makeList.bind(this, {i})}>edit</button>
                        </td>
                    </tr>;
                })
            })

        }

        render() {

            return <table>
                <tbody>
                    {this.state.list}
                </tbody>
            </table>
        }
    }




    ReactDOM.render(
            <App/>,
        document.getElementById("content")
    )

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Anton Spirin, 2018-12-10
@VGVolkov

1. Read about immutability.
2. Never change state directly.
3. If possible, do not bind in render.
4. Refactoring has nothing to do with redrawing the component.

createItem(task) {
  this.setState(prevState => ({
    tasks: [
      ...prevState.tasks,
      { name: task, status: false },
    ],
  }));
}

The rest of the code would be nice to rewrite, but how to do this is beyond the scope of your question.

V
Viktor Volkov, 2018-12-11
@VGVolkov

sorry) I was wrong, I meant rendering)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question